diff --git a/FoxIDs.sln b/FoxIDs.sln index a87738b01..24e2225bb 100644 --- a/FoxIDs.sln +++ b/FoxIDs.sln @@ -53,8 +53,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{CB5D86A0-D docs\email.md = docs\email.md docs\faq.md = docs\faq.md docs\getting-started.md = docs\getting-started.md + docs\howto-saml-2.0-context-handler.md = docs\howto-saml-2.0-context-handler.md docs\index.md = docs\index.md - docs\howto-saml-2.0-context-Handler.md = docs\howto-saml-2.0-context-Handler.md docs\language.md = docs\language.md docs\logging.md = docs\logging.md docs\login.md = docs\login.md @@ -141,6 +141,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "images", "images", "{CB8812 docs\images\howto-oidc-foxids-up-party-readredirect.png = docs\images\howto-oidc-foxids-up-party-readredirect.png docs\images\howto-oidc-foxids-up-party.png = docs\images\howto-oidc-foxids-up-party.png docs\images\howto-oidc-identityserver-readredirect.png = docs\images\howto-oidc-identityserver-readredirect.png + docs\images\howto-saml-context-handler-down-base-config.png = docs\images\howto-saml-context-handler-down-base-config.png + docs\images\howto-saml-context-handler-down-ct1.png = docs\images\howto-saml-context-handler-down-ct1.png + docs\images\howto-saml-context-handler-down-ct2.png = docs\images\howto-saml-context-handler-down-ct2.png + docs\images\howto-saml-context-handler-up-attributes.png = docs\images\howto-saml-context-handler-up-attributes.png + docs\images\howto-saml-context-handler-up-nameidformat.png = docs\images\howto-saml-context-handler-up-nameidformat.png + docs\images\howto-saml-context-handler-up-privilege-claim-tf.png = docs\images\howto-saml-context-handler-up-privilege-claim-tf.png + docs\images\howto-saml-context-handler-up-read-metadata.png = docs\images\howto-saml-context-handler-up-read-metadata.png docs\images\howto-saml-nemlogin3-certificate-container-type.png = docs\images\howto-saml-nemlogin3-certificate-container-type.png docs\images\howto-saml-nemlogin3-certificate.png = docs\images\howto-saml-nemlogin3-certificate.png docs\images\howto-saml-nemlogin3-claim-mappings.png = docs\images\howto-saml-nemlogin3-claim-mappings.png @@ -151,6 +158,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "images", "images", "{CB8812 docs\images\howto-saml-nemlogin3-up-claims.png = docs\images\howto-saml-nemlogin3-up-claims.png docs\images\howto-saml-nemlogin3-up-contact.png = docs\images\howto-saml-nemlogin3-up-contact.png docs\images\howto-saml-nemlogin3-up-nameidformat.png = docs\images\howto-saml-nemlogin3-up-nameidformat.png + docs\images\howto-saml-nemlogin3-up-privilege-claim-tf.png = docs\images\howto-saml-nemlogin3-up-privilege-claim-tf.png docs\images\howto-saml-nemlogin3-up-read-metadata.png = docs\images\howto-saml-nemlogin3-up-read-metadata.png docs\images\howto-saml-nemlogin3-up-top.png = docs\images\howto-saml-nemlogin3-up-top.png docs\images\master-tenant2.png = docs\images\master-tenant2.png diff --git a/docs/claim-transform-dk-privilege.md b/docs/claim-transform-dk-privilege.md index c7e5282bb..6beedd672 100644 --- a/docs/claim-transform-dk-privilege.md +++ b/docs/claim-transform-dk-privilege.md @@ -5,7 +5,7 @@ FoxIDs support claim transforms of DK privilege used in Danish IdPs like [NemLog Supported privilege standard: - [OIO Basic Privilege Profile, Version 1.2](https://digst.dk/media/20999/oiosaml-basic-privilege-profile-1_2.pdf) -- FoxIDs support PrivilegeGroup elements defined in [model 2](#model-2) (scoping and delegation) and [model 3](#model-3) (scoping, delegation and constraint). +- FoxIDs support `PrivilegeGroup` elements defined in [model 2](#model-2) (scoping and delegation) and [model 3](#model-3) (scoping, delegation and constraint). - FoxIDs support both to read the base64-encoded privilege string from the standard claim `https://data.gov.dk/model/core/eid/privilegesIntermediate` and a custom defined claim. ## Configuring DK privilege - claim transforms @@ -21,7 +21,7 @@ DK privilege claim transforms in [FoxIDs Control Client](control.md#foxids-contr ## Model 2 The DK privilege claim is transformed into a list of claims, one claim for each group. The XML PrivilegeGroup element is transformed into a JSON object and serialized as a string. -There are 4 possible scopes are translated into a property with a shorter name: +The 4 possible scopes are translated into a properties with a short name: - `Scope="urn:dk:gov:saml:cvrNumberIdentifier:"` become `"cvr": ""` - `Scope="urn:dk:gov:saml:productionUnitIdentifier:"` become `"p": ""` - `Scope="urn:dk:gov:saml:seNumberIdentifier:"` become `"se": ""` @@ -38,7 +38,7 @@ DK privilege base64-decoded sample: urn:dk:some_domain:myPrivilege1A urn:dk:some_domain:myPrivilege1B - + urn:dk:some_domain:myPrivilege1C urn:dk:some_domain:myPrivilege1D @@ -86,9 +86,9 @@ Is translated into one claims with JSON values: "p": [ "urn:dk:kombit:system_xyz:view_case" ] } -## Using JSON privilege claim +## Using JSON privilege claim in an application The [down-party](parties.md#down-party) application receives the privilege claim with the privilege serialized as a JSON string. -The following example show how to deserialize the JSON claim to an object in ASP.NET Core using `Newtonsoft.Json`. +The following C# code example show how to deserialize the JSON claim to an object in ASP.NET Core application using `Newtonsoft.Json`. Create privilege group class @@ -97,7 +97,7 @@ Create privilege group class [JsonProperty(PropertyName = "cvr")] public string CvrNumber { get; set; } - [JsonProperty(PropertyName = "P")] + [JsonProperty(PropertyName = "pu")] public string ProductionUnit { get; set; } [JsonProperty(PropertyName = "se")] diff --git a/docs/control.md b/docs/control.md index 41017e30c..30db687ed 100644 --- a/docs/control.md +++ b/docs/control.md @@ -63,7 +63,7 @@ FoxIDs Control API is a REST API. The API expose a Swagger (OpenApi) interface d FoxIDs Control API require that the client calling the API is granted the `foxids:master` scope to access master tenant data or the `foxids:tenant` scope access tenant data in a particular tenant. Normally only tenant data is accessed. - The client can be an OAuth 2.0 client. Where the client is granted the administrator role `foxids:tenant.admin` acting as the client itself using client credentials grant. - Her is how the [sample seed tool](https://localhost:44333/docs/samples#configure-the-sample-seed-tool) client is granted access. + Her is how the [sample seed tool](samples.md#configure-the-sample-seed-tool) client is granted access. - Or a OpenID Connect client with an authenticated master track user. Where the user is granted the administrator role `foxids:tenant.admin`. This shows the FoxIDs Control API configuration in a tenants master track with a scope that grants access to tenant data. diff --git a/docs/howto-saml-2.0-context-Handler.md b/docs/howto-saml-2.0-context-Handler.md deleted file mode 100644 index 97aaa7070..000000000 --- a/docs/howto-saml-2.0-context-Handler.md +++ /dev/null @@ -1,17 +0,0 @@ -# Up-party and down-party - Connect to Context Handler with SAML 2.0 - -// TODO - -FoxIDs can be connected to Context Handler (Danish IdP) with a [SAML 2.0 up-party](up-party-saml-2.0.md) and [SAML 2.0 down-party](down-party-saml-2.0.md). Where Context Handler is either a SAML 2.0 Identity Provider (IdP) or Relying Party (RP) and FoxIDs is acting as an SAML 2.0 Relying Party / Identity Provider. - -FoxIDs can transforms the [DK privilege XML claim](claim-transform-dk-privilege.md) to a JSON claim. - - -## Up-party - Connect to Context Handler - -*Context Handler is a SAML 2.0 Identity Provider (IdP)* - - -## Down-party - Connect to Context Handler - -*A FoxIDs down-party is a SAML 2.0 Identity Provider (IdP) and trusted by Context Handler* \ No newline at end of file diff --git a/docs/howto-saml-2.0-context-handler.md b/docs/howto-saml-2.0-context-handler.md new file mode 100644 index 000000000..f21dc6388 --- /dev/null +++ b/docs/howto-saml-2.0-context-handler.md @@ -0,0 +1,212 @@ +# Connect to Context Handler with SAML 2.0 +**Both up-party and down-party** + +FoxIDs can be connected to Context Handler (Danish IdP) with a [SAML 2.0 up-party](up-party-saml-2.0.md) and [SAML 2.0 down-party](down-party-saml-2.0.md). +Where Context Handler is either a SAML 2.0 [Identity Provider (IdP)](#configuring-context-handler-as-identity-provider-idp) or [Relying Party (RP)](#configuring-context-handler-as-relying-party-rp) and FoxIDs is acting as an SAML 2.0 Relying Party or Identity Provider. + +Context Handler is a Danish Identity Provider (IdP) connecting the Danish municipalities in a common federation. Context Handler can be configured based on either OIOSAML 2 or OIOSAML 3. FoxIDs support both OIOSAML 2 / OIOSAML 3, issuer naming, required certificates and it is possible to support NSIS. + +Context Handler documentation and configuration: +- The [Context Handler get started](https://digitaliseringskataloget.dk/l%C3%B8sninger/adgangsstyring-brugere). +- The [Context Handler administration portal](https://serviceplatformen.dk/administration/) +- The Context Handler [test application with NSIS](https://spwithnsis.eksterntest-stoettesystemerne.dk ) and [test application with out NSIS](https://spwithoutnsis.eksterntest-stoettesystemerne.dk) +- The [current/old Context Handler test application](https://demo-brugervendtsystem.kombit.dk/test) + +## Consider separate track + +Context Handler requires the Relying Party (RP) and Identity Provider (IdP) to use different OSES certificates. Therefore, consider connecting Context Handler in separate tracks where the OCES certificates can be configured without affecting any other configurations. + +Two FoxIDs tracks can be connected with OpenID Connect. Please see the [connect FoxIDs with OpenID Connect](up-party-howto-oidc-foxids.md) guide. The track with a up-party connected to Context Handler is called the parallel FoxIDs track in the guide. + +## Certificate + +Context Handler requires all requests (authn and logout) to be signed with OCES (FOCES/VOCES) certificates. It is not possible to use a certificate issued by another certificate authority, a self-signed certificate or a certificate issued by FoxIDs. + +An OCES certificate is valid for three years. After that, it must be updated manually. + +Add the `.P12` OCES certificate in [FoxIDs Control Client](control.md#foxids-control-client): +1. Select (or create) the track to be used for Context Handler as Relying Party (RP) or Identity Provider (IdP) +2. Select the Certificates tab +3. Click the arrow down on the Swap certificate button and then in the Contained certificates section click Change container type +4. Then click on the primary certificate, then write the password and upload the `.P12` OCES certificate + +![Add OCES certificate](images/howto-saml-nemlogin3-certificate.png) + +It is subsequently possible to add a secondary certificate and to swap between the primary and secondary certificates. + +## Configuring Context Handler as Identity Provider (IdP) + +*FoxIDs up-party is a SAML 2.0 Relying Party (RP) and trust Context Handler as an Identity Provider (IdP).* + +> You need to [configure the OCES certificate](#certificate) before following this configuration. + +**1 - Start by creating an SAML 2.0 up-party in [FoxIDs Control Client](control.md#foxids-control-client)** + +1. Select the Parties tab and then the Up-parties +2. Click Create up-party and then SMAL 2.0 +3. Add the name +4. Add the Context Handler IdP metadata in the Metadata URL field +5. Click Create +6. Change Logout response binding to Redirect + +> Currently Context Handler has an error where it does logout with a post binding. Therefore, after successfully configuration you need to change the Logout response binding back to post in order to make logout work. + +![Context Handler SAML 2.0 up-party](images/howto-saml-context-handler-up-read-metadata.png) + +7. Select show advanced settings +8. Configure a custom SP issuer, the issuer is required to start with `https://saml.` The issuer in this example `https://saml.localdev.foxids.com/test-corp/contexthandler-test/` +9. In production only! Set certificate validation mode to `Chain trust` and revocation mode to `Online` +10. Select to add logout response location URL in metadata +11. Select to include the encryption certificate in metadata +12. Set the NameID format in metadata to `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent` + +![Context Handler SAML 2.0 up-party](images/howto-saml-context-handler-up-nameidformat.png) + +13. Add an attribute consuming service in metadata and add the service name. +14. Add all the claims you want to receive as requested attributes with the format `urn:oasis:names:tc:SAML:2.0:attrname-format:uri`. Optionally set each attribute as required. + +The following claims is most often used: + + - Current/old Context Handler + - `dk:gov:saml:attribute:AssuranceLevel` + - `dk:gov:saml:attribute:CvrNumberIdentifier` + - (FamilyName) `urn:oid:2.5.4.4` + - `dk:gov:saml:attribute:Privileges_intermediate` + + - New NSIS Context Handler + - `https://data.gov.dk/concept/core/nsis/loa` + - `https://data.gov.dk/model/core/eid/professional/cvr` + - `https://data.gov.dk/model/core/eid/email` + - `https://data.gov.dk/model/core/eid/firstName` + - `https://data.gov.dk/model/core/eid/lastName` + - `https://data.gov.dk/model/core/eid/privilegesIntermediate` + +![Context Handler SAML 2.0 up-party](images/howto-saml-context-handler-up-attributes.png) + +15. Add at least one technical contact person +16. Click Update +17. Go to the top of the SAML 2.0 up-party +18. Find the SAML 2.0 up-party SP-metadata, in this case `https://localhost:44330/testcorp/test-contexthandler-rp/(ch-rp)/saml/spmetadata`. +19. The SP-metadata is used to configure the Context Handler user system (DK: brugervendt system). + +**2 - Then go to the [Context Handler administration portal](https://serviceplatformen.dk/administration/)** + +1. Select IT-systems (DK: IT-systemer) +2. Click Add IT-system (DK: Tilslut it-system) +3. Fill out the fields and select User system (DK: Brugervendt system) +4. Add the SAML 2.0 up-party SP-metadata in the user system (DK: Brugervendt system) tab. +5. Fill out the rest and click Save (DK: Gem) + + **3 - Add privilege claim transformation in [FoxIDs Control Client](control.md#foxids-control-client)** + +FoxIDs can transforms the [DK privilege XML claim](claim-transform-dk-privilege.md) to a JSON claim. It is recommended to add the transformation in order to obtain smaller claims and tokens. +Furthermore, it makes the tokens readable. + +1. Set the privilege claim `dk:gov:saml:attribute:Privileges_intermediate` or `https://data.gov.dk/model/core/eid/privilegesIntermediate` depending of the Context Handler version. +2. Remove the original privilege claim from the claims pipeline. +3. Click update + +![Context Handler SAML 2.0 up-party privilege claim transformation](images/howto-saml-context-handler-up-privilege-claim-tf.png) + + **4 - Add SAML 2.0 claim to JWT claim mappings in [FoxIDs Control Client](control.md#foxids-control-client)** + + FoxIDs internally converts SAML 2.0 clams to JWT claims. Context Handler use a OIOSAML 2 or OIOSAML 3 defined set of SAML 2.0 claims where corresponding JWT mappings need to be added. + + 1. Go to Settings tab and Claim mappings + 2. Add mappings for all the claims configured in step 1.14, you can create you own short JWT claim names if no standard name exists + 3. Click update + +You are done. The SAML 2.0 up-party can now be used as an up-party for down-parties in the track. + +> A down-party will only issue added claims. +> Therefore, remember to add the JWT claims to OpenID Connect down-parties or use the `*` notation. + +## Configuring Context Handler as Relying Party (RP) + +*FoxIDs down-party is a SAML 2.0 Identity Provider (IdP) and trusted by Context Handler acting as an Relying Party (RP).* + +> You need to [configure the OCES certificate](#certificate) before following this configuration. + +**1 - Start by creating an SAML 2.0 down-party in [FoxIDs Control Client](control.md#foxids-control-client)** + +1. Select the Parties tab and then the Down-parties +2. Click Create down-party and then SMAL 2.0 +3. Add the name +4. Select where the user should be allowed to login in Allow up-party names + +> Download the Context Handler RP metadata where you can find endpoints and the certificate to trust. The certificate is base64 and can be converted into a certificate .cer file with [FoxIDs certificate tool](https://www.foxids.com/tools/Certificate). + +5. Add the endpoints +6. Set the bindings to redirect with the exception of the Authn response binding which is set to post +7. Set the claims which should be issued to Context Handler (`NameId` / `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier` is default issued) + +The following claims is most often used: + + - Current/old Context Handler + - `dk:gov:saml:attribute:SpecVer` + - `dk:gov:saml:attribute:KombitSpecVer` + - `dk:gov:saml:attribute:AssuranceLevel` + - `dk:gov:saml:attribute:CvrNumberIdentifier` + - `dk:gov:saml:attribute:Privileges_intermediate` + + - New NSIS Context Handler + - `https://data.gov.dk/model/core/specVer` + - `https://data.gov.dk/model/core/kombitSpecVer` + - `https://data.gov.dk/concept/core/nsis/loa` + - `https://data.gov.dk/model/core/eid/professional/cvr` + - `https://data.gov.dk/model/core/eid/privilegesIntermediate` + +8. Add the Context Handler RP certificate as a signature validation certificate +9. Click Create + +![Context Handler SAML 2.0 down-party](images/howto-saml-context-handler-down-base-config.png) + +10. Select show advanced settings +11. In production only! Set certificate validation mode to `Chain trust` and revocation mode to `Online` +12. Configure a custom IdP issuer, the issuer is required to start with `https://saml.` The issuer in this example `https://saml.localdev-ipd.foxids.com/test-corp/test-contexthandler-idp/`. +13. Select to add logout response location URL in metadata +14. Select to include the encryption certificate in metadata +15. Set the NameID format in metadata to `urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName` +16. Click Update +17. Go to the top of the SAML 2.0 down-party +18. Find the SAML 2.0 down-party IdP-metadata, in this case `https://localhost:44330/testcorp/test-contexthandler-idp/ch-idp(*)/saml/idpmetadata`. +19. The IdP-metadata is used to configure the Context Handler identity provider. + +**2 - Then go to the [Context Handler administration portal](https://serviceplatformen.dk/administration/)** + +1. Select IT-systems (DK: IT-systemer) +2. Click Add IT-system (DK: Tilslut it-system) +3. Fill out the fields and select Identity Provider +4. Add the SAML 2.0 down-party IdP-metadata in the Identity Provider tab. +5. Fill out the rest and click Save (DK: Gem) + +> Additionally, a federation agreement (DK: føderationsaftaler) is required to enable the identity provider in Context Handler. + + **3 - Add claim transformation in [FoxIDs Control Client](control.md#foxids-control-client)** + +Create the claims which has to be issued to Context Handler in claim transforms. + +1. Add the spec. ver. claims +2. Optionally add the assurance level claim or read it through the claims pipeline + +![Context Handler SAML 2.0 down-party](images/howto-saml-context-handler-down-ct1.png) + +3. Replace the NameID / NameIdentifier claim which a concatenated version of the CVR number, display name and unique user ID. Format string `C=DK,O={0},CN={1} {2},Serial={3}` + +![Context Handler SAML 2.0 down-party](images/howto-saml-context-handler-down-ct2.png) + +4. Click update + + **4 - Add SAML 2.0 claim to JWT claim mappings in [FoxIDs Control Client](control.md#foxids-control-client)** + + FoxIDs internally converts SAML 2.0 clams to JWT claims. Context Handler use a OIOSAML 2 or OIOSAML 3 defined set of SAML 2.0 claims where corresponding JWT mappings need to be added. + + 1. Go to Settings tab and Claim mappings + 2. Add mappings for all the claims configured in step 1.7, you can create you own short JWT claim names if no standard name exists + 3. Click update + +**5 - Optionally add users in [FoxIDs Control Client](control.md#foxids-control-client)** + +You can add uses in the FoxIDs track and add claims to each user. + +E.g. a claim with a CVR claim, given name, family name and a base64 encoded [DK privilege XML](claim-transform-dk-privilege.md) string. diff --git a/docs/images/howto-saml-context-handler-down-base-config.png b/docs/images/howto-saml-context-handler-down-base-config.png new file mode 100644 index 000000000..d3008e1d5 Binary files /dev/null and b/docs/images/howto-saml-context-handler-down-base-config.png differ diff --git a/docs/images/howto-saml-context-handler-down-ct1.png b/docs/images/howto-saml-context-handler-down-ct1.png new file mode 100644 index 000000000..af73084fb Binary files /dev/null and b/docs/images/howto-saml-context-handler-down-ct1.png differ diff --git a/docs/images/howto-saml-context-handler-down-ct2.png b/docs/images/howto-saml-context-handler-down-ct2.png new file mode 100644 index 000000000..9ae637dfc Binary files /dev/null and b/docs/images/howto-saml-context-handler-down-ct2.png differ diff --git a/docs/images/howto-saml-context-handler-up-attributes.png b/docs/images/howto-saml-context-handler-up-attributes.png new file mode 100644 index 000000000..c05be34af Binary files /dev/null and b/docs/images/howto-saml-context-handler-up-attributes.png differ diff --git a/docs/images/howto-saml-context-handler-up-nameidformat.png b/docs/images/howto-saml-context-handler-up-nameidformat.png new file mode 100644 index 000000000..80da6a0e0 Binary files /dev/null and b/docs/images/howto-saml-context-handler-up-nameidformat.png differ diff --git a/docs/images/howto-saml-context-handler-up-privilege-claim-tf.png b/docs/images/howto-saml-context-handler-up-privilege-claim-tf.png new file mode 100644 index 000000000..48e28ab31 Binary files /dev/null and b/docs/images/howto-saml-context-handler-up-privilege-claim-tf.png differ diff --git a/docs/images/howto-saml-context-handler-up-read-metadata.png b/docs/images/howto-saml-context-handler-up-read-metadata.png new file mode 100644 index 000000000..eb581045d Binary files /dev/null and b/docs/images/howto-saml-context-handler-up-read-metadata.png differ diff --git a/docs/images/howto-saml-nemlogin3-up-privilege-claim-tf.png b/docs/images/howto-saml-nemlogin3-up-privilege-claim-tf.png new file mode 100644 index 000000000..5d686b30d Binary files /dev/null and b/docs/images/howto-saml-nemlogin3-up-privilege-claim-tf.png differ diff --git a/docs/up-party-howto-saml-2.0-nemlogin.md b/docs/up-party-howto-saml-2.0-nemlogin.md index 43e8bc19a..d394c81fd 100644 --- a/docs/up-party-howto-saml-2.0-nemlogin.md +++ b/docs/up-party-howto-saml-2.0-nemlogin.md @@ -6,10 +6,15 @@ FoxIDs can be connected to NemLog-in (Danish IdP) with a [up-party SAML 2.0](up- NemLog-in (currently called NemLog-in3) is a Danish Identity Provider (IdP) which uses the SAML 2.0 based OIOSAML 3. FoxIDs support NemLog-in / OIOSAML 3 including logging, issuer naming, required certificates and it is possible to support NSIS. -NemLog-in test and production environment: -- The [NemLog-in development portal](https://tu.nemlog-in.dk/oprettelse-og-administration-af-tjenester/), where you can find documentation and the NemLog-in IdP-metadata for test and production. -- The [NemLog-in development portal - test page](https://tu.nemlog-in.dk/oprettelse-og-administration-af-tjenester/log-in/dokumentation-og-guides/integrationstestmiljo/), where you can the NemLog-in IdP-metadata for test and FOCES2 / OCES3 test certificates. -- The [NemLog-in adminstration protal](https://administration.nemlog-in.dk/) where you configure IT-systems +NemLog-in documentation and configuration: +- The [NemLog-in development portal](https://tu.nemlog-in.dk/oprettelse-og-administration-af-tjenester/) with documentation + - [test](https://tu.nemlog-in.dk/oprettelse-og-administration-af-tjenester/log-in/dokumentation-og-guides/integrationstestmiljo/), where you can find the NemLog-in IdP-metadata for test and FOCES2 / OCES3 test certificates + - [production](https://tu.nemlog-in.dk/oprettelse-og-administration-af-tjenester/log-in/dokumentation-og-guides/produktionsmiljo/), where you can find the NemLog-in IdP-metadata for production +- The [NemLog-in administration portal](https://administration.nemlog-in.dk/) where you configure IT-systems +- Test environment + - Create citizens test users in [MitID emulator](https://pp.mitid.dk/test-tool/frontend/#/create-identity) + - Create citizens and employee test users in [MitID simulator](https://mitidsimulator.test-nemlog-in.dk/Home/Create) (login with username and password) + - OCES3 certificate - [create an organization](https://testportal.test-devtest4-nemlog-in.dk/TU) and [create OCES3 certificates](https://erhvervsadministration.devtest4-nemlog-in.dk/certificates) > A sample showing the NemLog-in integrations is configured in the FoxIDs `test-corp` with the up-party name `nemlogin_oidc`. The configuration uses a separate track where the NemLog-in integrations is configured and converted from SAMl 2.0 to OpenId Connect. > You can test NemLog-in login with the `AspNetCoreOidcAuthorizationCodeSample` [sample](samples.md#aspnetcoreoidcauthorizationcodesample) application by clicking `OIDC NemLog-in Log in` or by clicking `Log in` and then `Danish NemLog-in`. @@ -24,14 +29,14 @@ Two FoxIDs tracks can be connected with OpenID Connect. Please see the [connect NemLog-in requires all requests (authn and logout) from the Relying Party (RP) to be signed. Furthermore, NemLog-in requires the RP to sign with a OCES certificate. It is not possible to use a certificate issued by another certificate authority, a self-signed certificate or a certificate issued by FoxIDs. -A OCES certificate is valid for three years thereafter it manually has to be updated. +An OCES certificate is valid for three years. After that, it must be updated manually. Add the `.P12` OCES certificate in [FoxIDs Control Client](control.md#foxids-control-client): 1. Select (or create) the track to be used for NemLog-in 2. Select the Certificates tab 3. Click the arrow down on the Swap certificate button and then in the Contained certificates section click Change container type -![Add OCES certificate](images/howto-saml-nemlogin3-certificate-container-type.png) +![Change container type](images/howto-saml-nemlogin3-certificate-container-type.png) 4. Then click on the primary certificate, then write the password and upload the `.P12` OCES certificate @@ -105,7 +110,19 @@ It is subsequently possible to add a secondary certificate and to swap between t 4. Click the button Save the technical details 5. Click Provision to integrationtest and then click Apply for integration test - **3 - Add SAML 2.0 claim to JWT claim mappings in [FoxIDs Control Client](control.md#foxids-control-client)** + **3 - Optionally - add privilege claim transformation in [FoxIDs Control Client](control.md#foxids-control-client)** + +*Optionally, if you are using the privilege claim.* + +FoxIDs can transforms the [DK privilege XML claim](claim-transform-dk-privilege.md) to a JSON claim. It is recommended to add the transformation in order to obtain smaller claims and tokens. +Furthermore, it makes the tokens readable. + +1. Set the privilege claim depending of the Context Handler version. +2. Remove the original privilege claim from the claims pipeline. + +![NemLog-in SAML 2.0 up-party privilege claim transformation](images/howto-saml-nemlogin3-up-privilege-claim-tf.png) + + **4 - Add SAML 2.0 claim to JWT claim mappings in [FoxIDs Control Client](control.md#foxids-control-client)** FoxIDs internally converts SAML 2.0 clams to JWT claims. NemLog-in / OIOSAML 3 defines a set of SAML 2.0 claims where JWT mappings need to be added. @@ -118,7 +135,7 @@ It is subsequently possible to add a secondary certificate and to swap between t You are done. The SAML 2.0 up-party can now be used as an up-party for down-parties in the track. > A down-party will only issue added claims. -> Therefor, remember to add the JWT claims to OpenID Connect down-parties. +> Therefore, remember to add the JWT claims to OpenID Connect down-parties. See [Consider separate track](#consider-separate-track) on how to connect the NemLog-in track. diff --git a/src/FoxIDs.Control/FoxIDs.Control.csproj b/src/FoxIDs.Control/FoxIDs.Control.csproj index 1b37866bb..6b9bb531f 100644 --- a/src/FoxIDs.Control/FoxIDs.Control.csproj +++ b/src/FoxIDs.Control/FoxIDs.Control.csproj @@ -2,7 +2,7 @@ net7.0 - 1.0.11 + 1.0.12 FoxIDs Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs.ControlClient/FoxIDs.ControlClient.csproj b/src/FoxIDs.ControlClient/FoxIDs.ControlClient.csproj index 19c5e7a2c..ca4bf9e80 100644 --- a/src/FoxIDs.ControlClient/FoxIDs.ControlClient.csproj +++ b/src/FoxIDs.ControlClient/FoxIDs.ControlClient.csproj @@ -2,7 +2,7 @@ net7.0 - 1.0.11 + 1.0.12 FoxIDs.Client Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs.ControlClient/Pages/Components/EOAuthDownParty.cs b/src/FoxIDs.ControlClient/Pages/Components/EOAuthDownParty.cs index 9f4663267..3e07cac60 100644 --- a/src/FoxIDs.ControlClient/Pages/Components/EOAuthDownParty.cs +++ b/src/FoxIDs.ControlClient/Pages/Components/EOAuthDownParty.cs @@ -61,7 +61,7 @@ private OAuthDownPartyViewModel ToViewModel(GeneralOAuthDownPartyViewModel gener { generalOAuthDownParty.EnableClientTab = true; afterMap.Client.ExistingSecrets = oauthDownSecrets.Select(s => new OAuthClientSecretViewModel { Name = s.Name, Info = s.Info }).ToList(); - var defaultResourceScopeIndex = afterMap.Client.ResourceScopes.FindIndex(r => r.Resource.Equals(generalOAuthDownParty.Name, StringComparison.Ordinal)); + var defaultResourceScopeIndex = afterMap.Client.ResourceScopes.FindIndex(r => r.Resource.Equals(afterMap.Name, StringComparison.Ordinal)); if (defaultResourceScopeIndex > -1) { afterMap.Client.DefaultResourceScope = true; diff --git a/src/FoxIDs.ControlClient/Pages/Components/EOidcDownParty.cs b/src/FoxIDs.ControlClient/Pages/Components/EOidcDownParty.cs index dc1375b03..26508bd7f 100644 --- a/src/FoxIDs.ControlClient/Pages/Components/EOidcDownParty.cs +++ b/src/FoxIDs.ControlClient/Pages/Components/EOidcDownParty.cs @@ -60,7 +60,7 @@ private OidcDownPartyViewModel ToViewModel(GeneralOidcDownPartyViewModel general { generalOidcDownParty.EnableClientTab = true; afterMap.Client.ExistingSecrets = oidcDownSecrets.Select(s => new OAuthClientSecretViewModel { Name = s.Name, Info = s.Info }).ToList(); - var defaultResourceScopeIndex = afterMap.Client.ResourceScopes.FindIndex(r => r.Resource.Equals(generalOidcDownParty.Name, StringComparison.Ordinal)); + var defaultResourceScopeIndex = afterMap.Client.ResourceScopes.FindIndex(r => r.Resource.Equals(afterMap.Name, StringComparison.Ordinal)); if (defaultResourceScopeIndex > -1) { afterMap.Client.DefaultResourceScope = true; diff --git a/src/FoxIDs.ControlShared/FoxIDs.ControlShared.csproj b/src/FoxIDs.ControlShared/FoxIDs.ControlShared.csproj index 11121fae3..84519fb45 100644 --- a/src/FoxIDs.ControlShared/FoxIDs.ControlShared.csproj +++ b/src/FoxIDs.ControlShared/FoxIDs.ControlShared.csproj @@ -2,7 +2,7 @@ net7.0 - 1.0.11 + 1.0.12 FoxIDs Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs.Shared/FoxIDs.Shared.csproj b/src/FoxIDs.Shared/FoxIDs.Shared.csproj index 2ea12d03a..861cbfff6 100644 --- a/src/FoxIDs.Shared/FoxIDs.Shared.csproj +++ b/src/FoxIDs.Shared/FoxIDs.Shared.csproj @@ -2,7 +2,7 @@ net7.0 - 1.0.11 + 1.0.12 FoxIDs Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs.SharedBase/Constants.cs b/src/FoxIDs.SharedBase/Constants.cs index 4dd263646..51a933519 100644 --- a/src/FoxIDs.SharedBase/Constants.cs +++ b/src/FoxIDs.SharedBase/Constants.cs @@ -678,6 +678,8 @@ public static class DefaultClaimMappings new ClaimMap { JwtClaim = FoxI.JwtClaimTypes.SessionId, SamlClaim = Saml2ClaimTypes.SessionIndex }, new ClaimMap { JwtClaim = FoxI.JwtClaimTypes.Amr, SamlClaim = SamlClaimTypes.Amr }, new ClaimMap { JwtClaim = FoxI.JwtClaimTypes.Email, SamlClaim = ClaimTypes.Email }, + new ClaimMap { JwtClaim = FoxI.JwtClaimTypes.GivenName, SamlClaim = ClaimTypes.GivenName }, + new ClaimMap { JwtClaim = FoxI.JwtClaimTypes.FamilyName, SamlClaim = ClaimTypes.Surname }, new ClaimMap { JwtClaim = JwtClaimTypes.UpParty, SamlClaim = SamlClaimTypes.UpParty }, new ClaimMap { JwtClaim = JwtClaimTypes.UpPartyType, SamlClaim = SamlClaimTypes.UpPartyType }, new ClaimMap { JwtClaim = JwtClaimTypes.AccessToken, SamlClaim = SamlClaimTypes.AccessToken } diff --git a/src/FoxIDs.SharedBase/FoxIDs.SharedBase.csproj b/src/FoxIDs.SharedBase/FoxIDs.SharedBase.csproj index 20012db94..66fe013cf 100644 --- a/src/FoxIDs.SharedBase/FoxIDs.SharedBase.csproj +++ b/src/FoxIDs.SharedBase/FoxIDs.SharedBase.csproj @@ -2,7 +2,7 @@ net7.0 - 1.0.11 + 1.0.12 FoxIDs Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs/FoxIDs.csproj b/src/FoxIDs/FoxIDs.csproj index c335be95e..5fdec4cf0 100644 --- a/src/FoxIDs/FoxIDs.csproj +++ b/src/FoxIDs/FoxIDs.csproj @@ -1,7 +1,7 @@  net7.0 - 1.0.11 + 1.0.12 FoxIDs Anders Revsgaard ITfoxtec diff --git a/src/FoxIDs/Logic/Tracks/AccountActionLogic.cs b/src/FoxIDs/Logic/Tracks/AccountActionLogic.cs index a7b6bb077..a42387316 100644 --- a/src/FoxIDs/Logic/Tracks/AccountActionLogic.cs +++ b/src/FoxIDs/Logic/Tracks/AccountActionLogic.cs @@ -109,7 +109,7 @@ private async Task SaveAndSendEmailCode(IDatabase redisDb, string redisKey, stri var user = await accountLogic.GetUserAsync(email); if (user == null || user.DisableAccount) { - throw new UserNotExistsException($"User '{user.Email}' do not exist or is disabled, trying to send {logText} confirmation code."); + throw new UserNotExistsException($"User '{email}' do not exist or is disabled, trying to send {logText} confirmation code."); } await sendEmailLogic.SendEmailAsync(new MailAddress(user.Email, GetDisplayName(user)), emailContent(confirmationCode), fromName: RouteBinding.DisplayName); diff --git a/src/FoxIDs/Models/Logic/DkPrivilegeGroup.cs b/src/FoxIDs/Models/Logic/DkPrivilegeGroup.cs index 442bcfe27..d5a281b06 100644 --- a/src/FoxIDs/Models/Logic/DkPrivilegeGroup.cs +++ b/src/FoxIDs/Models/Logic/DkPrivilegeGroup.cs @@ -8,7 +8,7 @@ public class DkPrivilegeGroup [JsonProperty(PropertyName = "cvr")] public string CvrNumber { get; set; } - [JsonProperty(PropertyName = "P")] + [JsonProperty(PropertyName = "pu")] public string ProductionUnit { get; set; } [JsonProperty(PropertyName = "se")]