Skip to content

Commit

Permalink
Merge pull request #957 from ITfoxtec/test
Browse files Browse the repository at this point in the history
Test
  • Loading branch information
Revsgaard authored Sep 23, 2024
2 parents db9be21 + 117c4a4 commit e359ac4
Show file tree
Hide file tree
Showing 31 changed files with 219 additions and 86 deletions.
1 change: 0 additions & 1 deletion FoxIDs.sln
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "images", "images", "{CB8812
docs\images\howto-oidc-google-scopes.png = docs\images\howto-oidc-google-scopes.png
docs\images\howto-oidc-google-usertype.png = docs\images\howto-oidc-google-usertype.png
docs\images\howto-oidc-identityserver-readredirect.png = docs\images\howto-oidc-identityserver-readredirect.png
docs\images\howto-saml-claim-mappings.png = docs\images\howto-saml-claim-mappings.png
docs\images\howto-saml-context-handler-app-base-config-reg.png = docs\images\howto-saml-context-handler-app-base-config-reg.png
docs\images\howto-saml-context-handler-app-base-config.png = docs\images\howto-saml-context-handler-app-base-config.png
docs\images\howto-saml-context-handler-app-ct1.png = docs\images\howto-saml-context-handler-app-ct1.png
Expand Down
17 changes: 4 additions & 13 deletions docs/auth-method-howto-saml-2.0-nemlogin.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ Select show advanced settings and add the extension XML in **Authn request exten

![NemLog-in SAML 2.0 authn request extension XM](images/howto-saml-nemlogin3-auth-req-ext.png)

You can only configure one SAML 2.0 extension per authentication method in FoxIDs, therefor you might need to configure multiple authentication method for NemLog-in.
One authentication method for your web site without a SAML 2.0 extension, and one authentication method for each of the supported mobile app platforms.
You can configure authn request extensions XML in profiles on the authentication method. And then support multiple mobile platforms in profiles.

> As of now iOS do not require a return URL to do app-switch. But this can change over time!
> Therefor, you currently only need two authentication methods; one for your web site and iOS app without a redirect URL and one for your Android app with a redirect URL.
Expand All @@ -168,15 +167,7 @@ Furthermore, it makes the tokens readable.

![NemLog-in SAML 2.0 authentication method privilege claim transformation](images/howto-saml-privilege-claim-tf.png)

**5) - 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 / OIOSAML3 defines a set of SAML 2.0 claims where JWT mappings need to be added.

1. Go to the Settings tab and Claim mappings
2. Add mappings for all the claims configured in step 1.11, optionally also include mapping for the privilege claim, you can create you own short JWT claim names
3. Click update

![Claim mappings](images/howto-saml-nemlogin3-claim-mappings.png)
FoxIDs internally converts SAML 2.0 claims to JWT claims. The mapping between SAML 2.0 and JWT claims is automatically created by default. You can find and change the mapping in the **Settings** tab.

The SAML 2.0 authentication method can now be used as an authentication method for application registrations in the environment.

Expand Down Expand Up @@ -226,5 +217,5 @@ And possible credential types:
- `https://nemlogin.dk/internal/credential/type/test`


In the case you need to provide different sets of authn context class references. You need to create multiple SAML 2.0 authentication methods connected to NemLog-in as different IT systems.
E.g., if you need to support step-up authentication. Then you would create one SAML 2.0 authentication method with authn context class reference `https://data.gov.dk/concept/core/nsis/loa/Substantial` and another SAML 2.0 authentication method with authn context class reference `https://data.gov.dk/concept/core/nsis/loa/High`.
You can configure authn context class references in profiles on the authentication method. In the case you need to provide different sets of authn context class references.
E.g., if you need to support step-up authentication. Then you would create one profile with authn context class reference `https://data.gov.dk/concept/core/nsis/loa/Substantial` and another profile with authn context class reference `https://data.gov.dk/concept/core/nsis/loa/High`.
12 changes: 3 additions & 9 deletions docs/claim-transform-dk-privilege.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,17 @@ Supported privilege standard:
## Configuring DK privilege - claim transforms
The DK privilege can both be configured in a SAML 2.0 authentication method and application registration and likewise in a OpenID Connect authentication method and application registration.

- In SAML 2.0 the DK privilege claim transformer default read the standard claim `https://data.gov.dk/model/core/eid/privilegesIntermediate` and issue the transformed claim `http://schemas.foxids.com/identity/claims/privilege`.
- In OpenID Connect the DK privilege claim transformer default read the standard claim `privileges_intermediate` and issue the transformed claim `privilege`.
- The SAML 2.0 claim `https://data.gov.dk/model/core/eid/privilegesIntermediate` is transformed.
- The OpenID Connect / JWT claim `privileges_intermediate` is transformed.

Configure the DK privilege claim transformer on SAML 2.0 authentication method in [FoxIDs Control Client](control.md#foxids-control-client):

1. Select the **Claim transform** tab
2. Click **Add claim transform** and click **DK XML privilege to JSON**
3. Click **Add claim transform** and click **Match claim**
4. As **Action** select **Remove claim**, to remove the original privilege claim from the claims pipeline
5. In the **Remove claim** add `https://data.gov.dk/model/core/eid/privilegesIntermediate`
6. Click **Update**
3. Click **Update**

![Context Handler SAML 2.0 authentication method privilege claim transformation](images/howto-saml-privilege-claim-tf.png)


> Remember to add a [claim mapping](saml-2.0.md#claim-mappings) from SAML `http://schemas.foxids.com/identity/claims/privilege` to JWT `privilege` in the settings section. If you e.g. use a [SAML 2.0 authentication method](auth-method-saml-2.0.md) and a [OpenID Connect application registration](app-reg-oidc.md).
## 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.

Expand Down
23 changes: 5 additions & 18 deletions docs/howto-saml-2.0-context-handler.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,11 @@ Furthermore, it makes the tokens readable.

1. Select the **Claim transform** tab
2. Click **Add claim transform** and click **DK XML privilege to JSON**
3. Click **Add claim transform** and click **Match claim**
4. As **Action** select **Remove claim**, to remove the original privilege claim from the claims pipeline
5. In the **Remove claim** add `https://data.gov.dk/model/core/eid/privilegesIntermediate`
6. Click **Update**
3. Click **Update**

![Context Handler SAML 2.0 authentication method privilege claim transformation](images/howto-saml-privilege-claim-tf.png)

> Remember to add a claim mapping from SAML `http://schemas.foxids.com/identity/claims/privilege` to JWT `privilege` please see next section 4).
**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 OIOSAML3 defined set of SAML 2.0 claims where corresponding JWT mappings need to be added in the environment.

1. Go to Settings tab and Claim mappings
2. Click **Add claim mapping** 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**

![Context Handler SAML 2.0 claim mappings](images/howto-saml-claim-mappings.png)
FoxIDs internally converts SAML 2.0 claims to JWT claims. The mapping between SAML 2.0 and JWT claims is automatically created by default. You can find and change the mapping in the **Settings** tab.

You are done. The SAML 2.0 authentication method can now be used as an authentication method for application registrations in the environment.

Expand Down Expand Up @@ -260,10 +247,10 @@ Create the claims which has to be issued to Context Handler in claim transforms.

**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 OIOSAML3 defined set of SAML 2.0 claims where corresponding JWT mappings need to be added in the environment.
FoxIDs internally converts SAML 2.0 claims to JWT claims. Context Handler use a OIOSAML3 defined set of SAML 2.0 claims where corresponding JWT mappings need to be added in the environment.

1. Go to **Settings** tab and sub **Claim mappings** tab
2. Click **Add claim mapping** for all the claims configured in step 1.20, you can create you own short JWT claim names if no standard name exists - please see the corresponding information in section [Configuring Context Handler as Identity Provider](#configuring-context-handler-as-identity-provider) step 4
1. Go to Settings tab and Claim mappings
2. Click **Add claim mapping** for all the claims configured in step 1.20, you can create you own short JWT claim names if no standard name exists (or edit the claim mappings if they already exist)
3. Click **Update**

**5 - Add test users in [FoxIDs Control Client](control.md#foxids-control-client)**
Expand Down
Binary file modified docs/images/howto-saml-nemlogin3-auth-req-ext.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/images/howto-saml-privilege-claim-tf.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,6 @@ public TTrackClaimMappingController(TelemetryScopedLogger logger, IMapper mapper
{
if (!await ModelState.TryValidateObjectAsync(claimMappings)) return BadRequest(ModelState);

var duplicatedJwtClaimMappings = claimMappings.GroupBy(cm => cm.JwtClaim).Where(g => g.Count() > 1).Select(g => g.Key).FirstOrDefault();
if (duplicatedJwtClaimMappings != null)
{
ModelState.TryAddModelError(string.Empty, $"Duplicated JWT claim mappings '{duplicatedJwtClaimMappings}'");
return BadRequest(ModelState);
}

var trackIdKey = new Track.IdKey { TenantName = RouteBinding.TenantName, TrackName = RouteBinding.TrackName };
var mTrack = await tenantDataRepository.GetTrackByNameAsync(trackIdKey);

Expand Down
1 change: 1 addition & 0 deletions src/FoxIDs.Control/Controllers/Tracks/TTrackController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public TTrackController(FoxIDsControlSettings settings, TelemetryScopedLogger lo
var mTrack = await tenantDataRepository.GetTrackByNameAsync(trackIdKey);
mTrack.DisplayName = track.DisplayName;
mTrack.SequenceLifetime = track.SequenceLifetime;
mTrack.AutoMapSamlClaims = track.AutoMapSamlClaims;
mTrack.MaxFailingLogins = track.MaxFailingLogins;
mTrack.FailingLoginCountLifetime = track.FailingLoginCountLifetime;
mTrack.FailingLoginObservationPeriod = track.FailingLoginObservationPeriod;
Expand Down
2 changes: 1 addition & 1 deletion src/FoxIDs.Control/FoxIDs.Control.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>1.10.7</Version>
<Version>1.10.8</Version>
<RootNamespace>FoxIDs</RootNamespace>
<Authors>Anders Revsgaard</Authors>
<Company>ITfoxtec</Company>
Expand Down
2 changes: 1 addition & 1 deletion src/FoxIDs.ControlClient/FoxIDs.ControlClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>1.10.7</Version>
<Version>1.10.8</Version>
<RootNamespace>FoxIDs.Client</RootNamespace>
<Authors>Anders Revsgaard</Authors>
<Company>ITfoxtec</Company>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public TrackSettingsViewModel()
[Display(Name = "Sequence lifetime")]
public int SequenceLifetime { get; set; }

[Display(Name = "Automatically create mappings between JWT and SAML claim types")]
public bool AutoMapSamlClaims { get; set; }

[Range(Constants.Models.Track.MaxFailingLoginsMin, Constants.Models.Track.MaxFailingLoginsMax)]
[Display(Name = "Max failing logins")]
public int MaxFailingLogins { get; set; } = 5;
Expand Down
2 changes: 1 addition & 1 deletion src/FoxIDs.ControlClient/Pages/Certificates.razor
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
}
else
{
<button class="btn btn-link text-left p-0" @onclick="@(() => ShowUpdateCertificate(certificate))">
<button class="btn btn-link text-left p-0 btn-wrap" @onclick="@(() => ShowUpdateCertificate(certificate))">
<strong>@certificate.Subject</strong>
</button><br />
<span class="@(certificate.IsValid ? "" : "text-danger")">Valid from @certificate.ValidFrom.ToShortDateString() to @certificate.ValidTo.ToShortDateString()</span><br />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<FInputText @bind-Value="trackSettingsForm.Model.DisplayName" For="@(() => trackSettingsForm.Model.DisplayName)" />
<FFieldText @bind-Value="trackSettingsForm.Model.Name" For="@(() => trackSettingsForm.Model.Name)" />
<FInputNumber @bind-Value="trackSettingsForm.Model.SequenceLifetime" For="@(() => trackSettingsForm.Model.SequenceLifetime)" Focus="true" />
<FInputToggle @bind-Value="trackSettingsForm.Model.AutoMapSamlClaims" For="@(() => trackSettingsForm.Model.AutoMapSamlClaims)" TextType="e.d" />

<div class="mr-auto">
<h4 class="pt-5 pb-3">User & login settings</h4>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@
Model.ClaimTransforms.Add(new OAuthClaimTransformClaimInViewModel
{
ClaimIn = "privileges_intermediate",
ClaimOut = "privilege",
ClaimOut = "privileges_intermediate",
ShowDetails = true,
Action = ClaimTransformActions.Replace,
Type = claimTransformType
});
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@
Model.ClaimTransforms.Add(new SamlClaimTransformClaimInViewModel
{
ClaimIn = "https://data.gov.dk/model/core/eid/privilegesIntermediate",
ClaimOut = "http://schemas.foxids.com/identity/claims/privilege",
ClaimOut = "https://data.gov.dk/model/core/eid/privilegesIntermediate",
ShowDetails = true,
Action = ClaimTransformActions.Replace,
Type = claimTransformType
});
break;
Expand Down
1 change: 1 addition & 0 deletions src/FoxIDs.ControlClient/Shared/MainLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ private async Task OnCreateTrackValidSubmitAsync(EditContext editContext)
}
createTrackWorking = true;
var track = createTrackForm.Model.Map<Track>();
track.AutoMapSamlClaims = true;
var trackResponse = await TrackService.CreateTrackAsync(track);
createTrackForm.Model.Name = trackResponse.Name;
createTrackDone = true;
Expand Down
2 changes: 1 addition & 1 deletion src/FoxIDs.ControlShared/FoxIDs.ControlShared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>1.10.7</Version>
<Version>1.10.8</Version>
<RootNamespace>FoxIDs</RootNamespace>
<Authors>Anders Revsgaard</Authors>
<Company>ITfoxtec</Company>
Expand Down
3 changes: 3 additions & 0 deletions src/FoxIDs.ControlShared/Models/Api/Tracks/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ public class Track : INameValue, IValidatableObject
[Range(Constants.Models.Track.SequenceLifetimeMin, Constants.Models.Track.SequenceLifetimeMax)] // 30 seconds to 5 hours. Default 2 hours.
public int SequenceLifetime { get; set; } = Constants.TrackDefaults.DefaultSequenceLifetime;

[Display(Name = "Automatically create mappings between JWT and SAML claim types")]
public bool AutoMapSamlClaims { get; set; }

[Range(Constants.Models.Track.MaxFailingLoginsMin, Constants.Models.Track.MaxFailingLoginsMax)]
public int MaxFailingLogins { get; set; } = Constants.TrackDefaults.DefaultMaxFailingLogins;

Expand Down
2 changes: 1 addition & 1 deletion src/FoxIDs.Shared/FoxIDs.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Version>1.10.7</Version>
<Version>1.10.8</Version>
<RootNamespace>FoxIDs</RootNamespace>
<Authors>Anders Revsgaard</Authors>
<Company>ITfoxtec</Company>
Expand Down
4 changes: 3 additions & 1 deletion src/FoxIDs.Shared/Logic/MasterTenantLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public async Task CreateMasterTrackDocumentAsync(string tenantName)
DisplayName = "Master",
Name = trackName,
SequenceLifetime = 1800,
AutoMapSamlClaims = true,
MaxFailingLogins = 5,
FailingLoginCountLifetime = 36000,
FailingLoginObservationPeriod = 600,
Expand Down Expand Up @@ -262,7 +263,8 @@ private async Task CreateTrackDocumentsAsync(string tenantName, string trackDisp
var mTrack = new Track
{
DisplayName = trackDisplayName,
Name = trackName?.ToLower()
Name = trackName?.ToLower(),
AutoMapSamlClaims = true,
};
await CreateTrackDocumentAsync(tenantName, mTrack);
await CreateLoginDocumentAsync(tenantName, mTrack.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@
"id": 64
},
{
"name": "Initializing certificate in Key Vault",
"name": "Initialized new certificate",
"id": 65
},
{
"name": "The certificate will soon be ready. Please try again in a little while.",
"name": "The certificate is ready. Please try again.",
"id": 66
},
{
Expand Down Expand Up @@ -8990,7 +8990,7 @@
},
{
"culture": "en",
"value": "Initializing certificate in Key Vault",
"value": "Initialized new certificate",
"edit_level": 100
},
{
Expand Down Expand Up @@ -9125,7 +9125,7 @@
},
{
"culture": "en",
"value": "The certificate will soon be ready. Please try again in a little while.",
"value": "The certificate is ready. Please try again.",
"edit_level": 100
},
{
Expand Down
2 changes: 2 additions & 0 deletions src/FoxIDs.Shared/Models/Routes/RouteBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class RouteBinding

public List<ClaimMap> ClaimMappings { get; set; }

public bool AutoMapSamlClaims { get; set; }

public List<ResourceItem> Resources { get; set; }

public bool ShowResourceId { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions src/FoxIDs.Shared/Models/Tracks/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public static async Task<string> IdFormatAsync(RouteBinding routeBinding, string
[JsonProperty(PropertyName = "claim_mappings")]
public List<ClaimMap> ClaimMappings { get; set; }

[JsonProperty(PropertyName = "auto_map_saml_claims")]
public bool AutoMapSamlClaims { get; set; }

[ListLength(Constants.Models.Track.ResourcesMin, Constants.Models.Track.ResourcesMax)]
[JsonProperty(PropertyName = "resources")]
public List<ResourceItem> Resources { get; set; }
Expand Down
Loading

0 comments on commit e359ac4

Please sign in to comment.