-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add prefill capability to localtest (#8563)
* Add prefill capability to localtest * use System.text.json * Fix LGTM warnings * Improve debug information * Reorder codelines to keep definition closer to usage * Fix typo. * Increase Loadbalancer timeout for localtest * Get orgnumber for OrgToken from cdn Also lots of cleanup * Ensure that prefill upload is only availibel for LocalAppMode == http * Update src/development/LocalTest/Services/LocalApp/Implementation/LocalAppHttp.cs * Update src/development/LocalTest/Services/Authentication/Implementation/AuthenticationService.cs Co-authored-by: Ivar <[email protected]>
- Loading branch information
Showing
14 changed files
with
292 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#nullable enable | ||
using System.Net.Http; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
|
||
namespace LocalTest.Clients.CdnAltinnOrgs; | ||
|
||
/// <summary> | ||
/// Access data from https://altinncdn.no/orgs/altinn-orgs.json | ||
/// </summary> | ||
public class AltinnOrgsClient | ||
{ | ||
private static JsonSerializerOptions JSON_OPTIONS = new JsonSerializerOptions(JsonSerializerDefaults.Web); | ||
private readonly HttpClient _client; | ||
|
||
public AltinnOrgsClient(HttpClient client) | ||
{ | ||
_client = client; | ||
} | ||
|
||
public async Task<CdnOrgs> GetCdnOrgs() | ||
{ | ||
var orgsJson = await _client.GetByteArrayAsync("https://altinncdn.no/orgs/altinn-orgs.json"); | ||
return JsonSerializer.Deserialize<CdnOrgs>(orgsJson, JSON_OPTIONS) ?? throw new JsonException("altinn-orgs respones was \"null\""); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#nullable enable | ||
using System.Collections.Generic; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace LocalTest.Clients.CdnAltinnOrgs; | ||
|
||
public class CdnOrgs | ||
{ | ||
[JsonPropertyName("orgs")] | ||
public Dictionary<string,CdnOrg>? Orgs { get; set; } | ||
} | ||
|
||
public class CdnOrg | ||
{ | ||
[JsonPropertyName("name")] | ||
public CdnOrgName? Name { get; set; } | ||
|
||
[JsonPropertyName("logo")] | ||
public string? Logo { get; set; } | ||
|
||
[JsonPropertyName("orgnr")] | ||
public string? Orgnr { get; set; } | ||
|
||
[JsonPropertyName("homepage")] | ||
public string? Homepage { get; set; } | ||
|
||
[JsonPropertyName("environments")] | ||
public List<string>? Environments { get; set; } | ||
|
||
} | ||
|
||
public class CdnOrgName | ||
{ | ||
[JsonPropertyName("nb")] | ||
public string? Nb { get; set; } | ||
|
||
[JsonPropertyName("nn")] | ||
public string? Nn { get; set; } | ||
|
||
[JsonPropertyName("en")] | ||
public string? En { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 87 additions & 21 deletions
108
src/Services/Authentication/Implementation/AuthenticationService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,105 @@ | ||
#nullable enable | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IdentityModel.Tokens.Jwt; | ||
using System.Security.Claims; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
using System.Threading.Tasks; | ||
using AuthSettings = Altinn.Platform.Authentication.Configuration.GeneralSettings; | ||
using Altinn.Platform.Profile.Models; | ||
using LocalTest.Clients.CdnAltinnOrgs; | ||
using LocalTest.Services.Authentication.Interface; | ||
|
||
using Microsoft.Extensions.Options; | ||
using Microsoft.IdentityModel.Tokens; | ||
using LocalTest.Configuration; | ||
using AltinnCore.Authentication.Constants; | ||
using Altinn.Platform.Authorization.Services.Interface; | ||
|
||
namespace LocalTest.Services.Authentication.Implementation; | ||
|
||
namespace LocalTest.Services.Authentication.Implementation | ||
public class AuthenticationService : IAuthentication | ||
{ | ||
public class AuthenticationService : IAuthentication | ||
private readonly AltinnOrgsClient _orgsClient; | ||
private readonly AuthSettings _authSettings; | ||
private readonly GeneralSettings _generalSettings; | ||
private readonly IClaims _claimsService; | ||
|
||
public AuthenticationService(AltinnOrgsClient orgsClient, IOptions<AuthSettings> authSettings, IOptions<GeneralSettings> generalSettings, IClaims claimsService) | ||
{ | ||
_orgsClient = orgsClient; | ||
_authSettings = authSettings.Value; | ||
_generalSettings = generalSettings.Value; | ||
_claimsService = claimsService; | ||
} | ||
///<inheritdoc/> | ||
public string GenerateToken(ClaimsPrincipal principal) | ||
{ | ||
///<inheritdoc/> | ||
public string GenerateToken(ClaimsPrincipal principal, int cookieValidityTime) | ||
List<X509Certificate2> certificates = new List<X509Certificate2> | ||
{ | ||
List<X509Certificate2> certificates = new List<X509Certificate2> | ||
{ | ||
new X509Certificate2("jwtselfsignedcert.pfx", "qwer1234") // lgtm [cs/hardcoded-credentials] | ||
}; | ||
new X509Certificate2("jwtselfsignedcert.pfx", "qwer1234") // lgtm [cs/hardcoded-credentials] | ||
}; | ||
|
||
TimeSpan tokenExpiry = new TimeSpan(0, cookieValidityTime, 0); | ||
TimeSpan tokenExpiry = new TimeSpan(0, _authSettings.GetJwtCookieValidityTime, 0); | ||
|
||
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); | ||
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor | ||
{ | ||
Subject = new ClaimsIdentity(principal.Identity), | ||
Expires = DateTime.UtcNow.AddSeconds(tokenExpiry.TotalSeconds), | ||
SigningCredentials = new X509SigningCredentials(certificates[0]) | ||
}; | ||
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); | ||
SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor | ||
{ | ||
Subject = new ClaimsIdentity(principal.Identity), | ||
Expires = DateTime.UtcNow.AddSeconds(tokenExpiry.TotalSeconds), | ||
SigningCredentials = new X509SigningCredentials(certificates[0]) | ||
}; | ||
|
||
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); | ||
string serializedToken = tokenHandler.WriteToken(token); | ||
|
||
SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); | ||
string serializedToken = tokenHandler.WriteToken(token); | ||
return serializedToken; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task<string> GenerateTokenForOrg(string org, string? orgNumber = null) | ||
{ | ||
if (orgNumber is null) | ||
{ | ||
var orgs = await _orgsClient.GetCdnOrgs(); | ||
orgNumber = (orgs.Orgs?.TryGetValue(org, out var value) == true ? value : null)?.Orgnr; | ||
} | ||
|
||
return serializedToken; | ||
List<Claim> claims = new List<Claim>(); | ||
string issuer = _generalSettings.Hostname; | ||
claims.Add(new Claim(AltinnCoreClaimTypes.Org, org.ToLower(), ClaimValueTypes.String, issuer)); | ||
// 3 is the default level for altinn tokens form Maskinporten | ||
claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticationLevel, "3", ClaimValueTypes.Integer32, issuer)); | ||
claims.Add(new Claim("urn:altinn:scope", "altinn:serviceowner/instances.read", ClaimValueTypes.String, issuer)); | ||
if (!string.IsNullOrEmpty(orgNumber)) | ||
{ | ||
claims.Add(new Claim(AltinnCoreClaimTypes.OrgNumber, orgNumber, ClaimValueTypes.String, issuer)); | ||
} | ||
|
||
ClaimsIdentity identity = new ClaimsIdentity(_generalSettings.GetClaimsIdentity); | ||
identity.AddClaims(claims); | ||
ClaimsPrincipal principal = new ClaimsPrincipal(identity); | ||
|
||
// Create a test token with long duration | ||
return GenerateToken(principal); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task<string> GenerateTokenForProfile(UserProfile profile, int authenticationLevel) | ||
{ | ||
List<Claim> claims = new List<Claim>(); | ||
string issuer = _generalSettings.Hostname; | ||
claims.Add(new Claim(ClaimTypes.NameIdentifier, profile.UserId.ToString(), ClaimValueTypes.String, issuer)); | ||
claims.Add(new Claim(AltinnCoreClaimTypes.UserId, profile.UserId.ToString(), ClaimValueTypes.String, issuer)); | ||
claims.Add(new Claim(AltinnCoreClaimTypes.UserName, profile.UserName, ClaimValueTypes.String, issuer)); | ||
claims.Add(new Claim(AltinnCoreClaimTypes.PartyID, profile.PartyId.ToString(), ClaimValueTypes.Integer32, issuer)); | ||
claims.Add(new Claim(AltinnCoreClaimTypes.AuthenticationLevel, authenticationLevel.ToString(), ClaimValueTypes.Integer32, issuer)); | ||
claims.AddRange(await _claimsService.GetCustomClaims(profile.UserId, issuer)); | ||
|
||
ClaimsIdentity identity = new ClaimsIdentity(_generalSettings.GetClaimsIdentity); | ||
identity.AddClaims(claims); | ||
ClaimsPrincipal principal = new ClaimsPrincipal(identity); | ||
|
||
return GenerateToken(principal); | ||
} | ||
} | ||
|
Oops, something went wrong.