public async Task <JwsPayload> GenerateAccessToken(Client client, IEnumerable <string> scopes) { if (client == null) { throw new ArgumentNullException(nameof(client)); } if (scopes == null) { throw new ArgumentNullException(nameof(scopes)); } var timeKeyValuePair = await GetExpirationAndIssuedTime(); var expirationInSeconds = timeKeyValuePair.Key; var issuedAtTime = timeKeyValuePair.Value; var jwsPayload = new JwsPayload(); jwsPayload.Add(StandardClaimNames.ExpirationTime, expirationInSeconds); jwsPayload.Add(StandardClaimNames.Iat, issuedAtTime); jwsPayload.Add(StandardClaimNames.ClientId, client.ClientId); jwsPayload.Add(StandardClaimNames.Scopes, scopes); return(jwsPayload); }
public void WhenBuildClaimToken(Table table) { var jwsPayload = new JwsPayload(); foreach (var record in table.Rows) { var key = record["Key"]; var value = record["Value"]; if (value.StartsWith('[') && value.EndsWith(']')) { value = value.TrimStart('[').TrimEnd(']'); var splitted = value.Split(','); jwsPayload.Add(key, JArray.FromObject(splitted)); } else { jwsPayload.Add(key, value); } } var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var jws = jwtBuilder.Sign(jwsPayload, JwksStore.GetInstance().GetJsonWebKey()); _scenarioContext.Set(jws, "claim_token"); }
private void AddExpirationAndIssueTime(JwsPayload jwsPayload, double validityPeriodsInSeconds) { var currentDateTime = DateTime.UtcNow; var expirationDateTime = currentDateTime.AddSeconds(validityPeriodsInSeconds); jwsPayload.Add(OAuthClaims.Iat, currentDateTime.ConvertToUnixTimestamp()); jwsPayload.Add(OAuthClaims.ExpirationTime, expirationDateTime.ConvertToUnixTimestamp()); }
public void WhenBuildSoftwareStatement(Table table) { var jwsPayload = new JwsPayload(); foreach (var record in table.Rows) { var key = record["Key"]; var value = record["Value"]; if (value.StartsWith('[') && value.EndsWith(']')) { value = value.TrimStart('[').TrimEnd(']'); var splitted = value.Split(','); jwsPayload.Add(key, JArray.FromObject(splitted)); } else { jwsPayload.Add(key, value); } } var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var jwk = FakeJwks.GetInstance().Jwks.First(); var jws = jwtBuilder.Sign(jwsPayload, jwk, jwk.Alg); _scenarioContext.Set(jws, "softwareStatement"); }
public async Task <JwsPayload> UpdatePayloadDate(JwsPayload jwsPayload) { if (jwsPayload == null) { throw new ArgumentNullException(nameof(jwsPayload)); } var timeKeyValuePair = await GetExpirationAndIssuedTime(); var expirationInSeconds = timeKeyValuePair.Key; var issuedAtTime = timeKeyValuePair.Value; if (jwsPayload.ContainsKey(StandardClaimNames.Iat)) { jwsPayload[StandardClaimNames.Iat] = issuedAtTime; } else { jwsPayload.Add(StandardClaimNames.Iat, issuedAtTime); } if (jwsPayload.ContainsKey(StandardClaimNames.ExpirationTime)) { jwsPayload[StandardClaimNames.ExpirationTime] = expirationInSeconds; } else { jwsPayload.Add(StandardClaimNames.ExpirationTime, expirationInSeconds); } return(jwsPayload); }
private async Task FillInResourceOwnerClaimsFromScopes( JwsPayload jwsPayload, AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal) { // 1. Fill-in the subject claim var subject = claimsPrincipal.GetSubject(); jwsPayload.Add(Jwt.Constants.StandardResourceOwnerClaimNames.Subject, subject); if (authorizationParameter == null || string.IsNullOrWhiteSpace(authorizationParameter.Scope)) { return; } // 2. Fill-in the other claims var scopes = _parameterParserHelper.ParseScopes(authorizationParameter.Scope); var claims = await GetClaimsFromRequestedScopes(scopes, claimsPrincipal); foreach (var claim in claims) { if (claim.Key == Jwt.Constants.StandardResourceOwnerClaimNames.Subject) { continue; } jwsPayload.Add(claim.Key, claim.Value); } }
private static void Init(JwsPayload payload) { if (!payload.ContainsKey(CLAIM_NAMES)) { payload.Add(CLAIM_NAMES, new JObject()); } if (!payload.ContainsKey(CLAIM_SOURCES)) { payload.Add(CLAIM_SOURCES, new JObject()); } }
public async Task When_Pass_IdTokenHint_And_The_Subject_Doesnt_Match_Then_Error_Is_Returned() { // GENERATE JWS InitializeFakeObjects(); _httpClientFactoryStub.Setup(h => h.GetHttpClient()).Returns(_server.Client); var payload = new JwsPayload { { "sub", "adm" } }; payload.Add("aud", new[] { "http://localhost:5000" }); var jws = _jwsGenerator.Generate(payload, JwsAlg.RS256, _server.SharedCtx.SignatureKey); // ACT var result = await _authorizationClient.ResolveAsync(baseUrl + "/.well-known/openid-configuration", new AuthorizationRequest(new[] { "openid", "api1" }, new[] { ResponseTypes.Code }, "authcode_client", "http://localhost:5000/callback", "state") { IdTokenHint = jws, Prompt = "none" }); // ASSERT Assert.NotNull(result); Assert.True(result.ContainsError); Assert.Equal("invalid_request", result.Error.Error); Assert.Equal("the current authenticated user doesn't match with the identity token", result.Error.ErrorDescription); }
public async Task When_Pass_IdTokenHint_And_The_Subject_Matches_The_Authenticated_User_Then_Token_Is_Returned() { // GENERATE JWS InitializeFakeObjects(); _httpClientFactoryStub.Setup(h => h.GetHttpClient()).Returns(_server.Client); var payload = new JwsPayload { { "sub", "administrator" } }; payload.Add("aud", new[] { "http://localhost:5000" }); var jws = _jwsGenerator.Generate(payload, JwsAlg.RS256, _server.SharedCtx.SignatureKey); var jwe = _jweGenerator.GenerateJwe(jws, JweAlg.RSA1_5, JweEnc.A128CBC_HS256, _server.SharedCtx.EncryptionKey); // ACT var result = await _authorizationClient.ResolveAsync(baseUrl + "/.well-known/openid-configuration", new AuthorizationRequest(new[] { "openid", "api1" }, new[] { ResponseTypes.Code }, "authcode_client", "http://localhost:5000/callback", "state") { IdTokenHint = jwe, Prompt = "none" }); // ASSERT Assert.NotNull(result); Assert.False(result.ContainsError); }
public void WhenBuildJWS(string kid, string jwksName, string name, Table table) { var jwks = _scenarioContext.Get <List <JsonWebKey> >(jwksName); kid = ParseValue(kid).ToString(); name = ParseValue(name).ToString(); var jwk = jwks.First(j => j.Kid == kid); var jwsPayload = new JwsPayload(); foreach (var row in table.Rows) { var key = row["Key"]; var value = ParseValue(row["Value"]); jwsPayload.Add(key, value); } var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var jws = jwtBuilder.Sign(jwsPayload, jwk, jwk.Alg); _scenarioContext.Set(jws, name); var tokenCommandRepository = (ITokenRepository)_factory.Server.Host.Services.GetService(typeof(ITokenRepository)); tokenCommandRepository.Add(new Token { Id = jws, CreateDateTime = DateTime.UtcNow, TokenType = "access_token" }, CancellationToken.None).Wait(); }
private void FillInResourceOwnerClaimsByClaimsParameter( JwsPayload jwsPayload, List <ClaimParameter> claimParameters, ClaimsPrincipal claimsPrincipal, AuthorizationParameter authorizationParameter) { var state = authorizationParameter == null ? string.Empty : authorizationParameter.State; // 1. Fill-In the subject - set the subject as an essential claim if (claimParameters.All(c => c.Name != Jwt.Constants.StandardResourceOwnerClaimNames.Subject)) { var essentialSubjectClaimParameter = new ClaimParameter { Name = Jwt.Constants.StandardResourceOwnerClaimNames.Subject, Parameters = new Dictionary <string, object> { { Constants.StandardClaimParameterValueNames.EssentialName, true } } }; claimParameters.Add(essentialSubjectClaimParameter); } // 2. Fill-In all the other resource owner claims if (claimParameters == null || !claimParameters.Any()) { return; } var resourceOwnerClaimParameters = claimParameters .Where(c => Jwt.Constants.AllStandardResourceOwnerClaimNames.Contains(c.Name)) .ToList(); if (resourceOwnerClaimParameters.Any()) { var requestedClaimNames = resourceOwnerClaimParameters.Select(r => r.Name); var resourceOwnerClaims = GetClaims(requestedClaimNames, claimsPrincipal); foreach (var resourceOwnerClaimParameter in resourceOwnerClaimParameters) { var resourceOwnerClaim = resourceOwnerClaims.FirstOrDefault(c => c.Key == resourceOwnerClaimParameter.Name); var resourceOwnerClaimValue = resourceOwnerClaim.Equals(default(KeyValuePair <string, string>)) ? string.Empty : resourceOwnerClaim.Value; var isClaimValid = ValidateClaimValue(resourceOwnerClaimValue, resourceOwnerClaimParameter); if (!isClaimValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, resourceOwnerClaimParameter.Name), state); } jwsPayload.Add(resourceOwnerClaim.Key, resourceOwnerClaim.Value); } } }
public void FillInOtherClaimsIdentityTokenPayload(JwsPayload jwsPayload, string authorizationCode, string accessToken, AuthorizationParameter authorizationParameter, Client client) { if (jwsPayload == null) { throw new ArgumentNullException(nameof(jwsPayload)); } if (client == null) { throw new ArgumentNullException(nameof(client)); } var signedAlg = client.GetIdTokenSignedResponseAlg(); if (signedAlg == null || signedAlg == JwsAlg.none) { return; } if (!_mappingJwsAlgToHashingFunctions.ContainsKey(signedAlg.Value)) { throw new InvalidOperationException(string.Format("the alg {0} is not supported", signedAlg.Value)); } var callback = _mappingJwsAlgToHashingFunctions[signedAlg.Value]; if (!string.IsNullOrWhiteSpace(authorizationCode)) { var hashingAuthorizationCode = callback(authorizationCode); jwsPayload.Add(Jwt.Constants.StandardClaimNames.CHash, hashingAuthorizationCode); } if (!string.IsNullOrWhiteSpace(accessToken)) { var hashingAccessToken = callback(accessToken); jwsPayload.Add(Jwt.Constants.StandardClaimNames.AtHash, hashingAccessToken); } }
public override void EnrichWithClaimsParameter(JwsPayload payload, IEnumerable <AuthorizationRequestClaimParameter> requestedClaims, OAuthUser user = null, DateTime?authDateTime = null, AuthorizationRequestClaimTypes claimType = AuthorizationRequestClaimTypes.IdToken) { base.EnrichWithClaimsParameter(payload, requestedClaims, user, authDateTime, claimType); if (requestedClaims != null) { var requestedClaim = requestedClaims.FirstOrDefault(c => c.Name == _options.OpenBankingApiConsentClaimName); if (requestedClaim != null) { payload.Add(_options.OpenBankingApiConsentClaimName, requestedClaim.Values.First()); } } }
protected virtual async Task <JwsPayload> BuildIdToken(HandlerContext currentContext, JObject queryParameters, IEnumerable <string> requestedScopes, CancellationToken cancellationToken) { var openidClient = (OpenIdClient)currentContext.Client; var result = new JwsPayload { { OAuthClaims.Audiences, new [] { openidClient.ClientId, currentContext.Request.IssuerName } }, { OAuthClaims.Issuer, currentContext.Request.IssuerName }, { OAuthClaims.Iat, DateTime.UtcNow.ConvertToUnixTimestamp() }, { OAuthClaims.ExpirationTime, DateTime.UtcNow.AddSeconds(openidClient.TokenExpirationTimeInSeconds).ConvertToUnixTimestamp() }, { OAuthClaims.Azp, openidClient.ClientId } }; var maxAge = queryParameters.GetMaxAgeFromAuthorizationRequest(); var nonce = queryParameters.GetNonceFromAuthorizationRequest(); var acrValues = queryParameters.GetAcrValuesFromAuthorizationRequest(); var requestedClaims = queryParameters.GetClaimsFromAuthorizationRequest(); var subjectTypeBuilder = _subjectTypeBuilders.First(f => f.SubjectType == (string.IsNullOrWhiteSpace(openidClient.SubjectType) ? PublicSubjectTypeBuilder.SUBJECT_TYPE : openidClient.SubjectType)); var subject = await subjectTypeBuilder.Build(currentContext); string accessToken, code; if (currentContext.Response.TryGet(OAuth.DTOs.AuthorizationResponseParameters.AccessToken, out accessToken)) { result.Add(OAuthClaims.AtHash, ComputeHash(accessToken)); } if (currentContext.Response.TryGet(OAuth.DTOs.AuthorizationResponseParameters.Code, out code)) { result.Add(OAuthClaims.CHash, ComputeHash(code)); } if (maxAge != null) { result.Add(OAuthClaims.AuthenticationTime, currentContext.User.AuthenticationTime.Value.ConvertToUnixTimestamp()); } if (!string.IsNullOrWhiteSpace(nonce)) { result.Add(OAuthClaims.Nonce, nonce); } var defaultAcr = await _amrHelper.FetchDefaultAcr(acrValues, requestedClaims, openidClient, cancellationToken); if (defaultAcr != null) { result.Add(OAuthClaims.Amr, defaultAcr.AuthenticationMethodReferences); result.Add(OAuthClaims.Acr, defaultAcr.Name); } var scopes = openidClient.AllowedOpenIdScopes.Where(s => requestedScopes.Any(r => r == s.Name)); EnrichWithScopeParameter(result, scopes, currentContext.User, subject); _claimsJwsPayloadEnricher.EnrichWithClaimsParameter(result, requestedClaims, currentContext.User, currentContext.User.AuthenticationTime); foreach (var claimsSource in _claimsSources) { await claimsSource.Enrich(result, openidClient).ConfigureAwait(false); } return(result); }
public async Task Enrich(JwsPayload result, JObject queryParameters, CancellationToken cancellationToken) { var authRequestId = queryParameters.GetAuthRequestId(); if (!string.IsNullOrWhiteSpace(authRequestId)) { var authorize = await _bcAuthorizeRepository.Get(authRequestId, cancellationToken); if (authorize != null && authorize.Permissions.Any()) { var firstPermission = authorize.Permissions.First(); if (result.ContainsKey(_options.OpenBankingApiConsentClaimName)) { result[_options.OpenBankingApiConsentClaimName] = firstPermission.ConsentId; } else { result.Add(_options.OpenBankingApiConsentClaimName, firstPermission.ConsentId); } } if (authorize.Scopes.Contains(SIDOpenIdConstants.StandardScopes.OpenIdScope.Name) && !result.ContainsKey(UserClaims.Subject)) { result.Add(UserClaims.Subject, authorize.UserId); } } var requestedClaims = queryParameters.GetClaimsFromAuthorizationRequest(); if (requestedClaims != null) { var requestedClaim = requestedClaims.FirstOrDefault(c => c.Name == _options.OpenBankingApiConsentClaimName); if (requestedClaim != null) { result.Add(_options.OpenBankingApiConsentClaimName, requestedClaim.Values.First()); } } }
private async Task <string> BuildJws(string clientId, Table table) { var accessTokenPayload = new JwsPayload(); foreach (var row in table.Rows) { var values = row["Value"].Split(","); if (values.Count() > 1 && !row["Value"].StartsWith("{")) { var jArr = new JArray(values.ToArray()); accessTokenPayload.Add(row["Key"], jArr); } else { accessTokenPayload.Add(row["Key"], row["Value"]); } } var clientRepository = (IOAuthClientQueryRepository)_factory.Server.Host.Services.GetService(typeof(IOAuthClientQueryRepository)); var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var oauthClient = (OpenIdClient)await clientRepository.FindOAuthClientById(clientId); return(await jwtBuilder.BuildClientToken(oauthClient, accessTokenPayload, oauthClient.IdTokenSignedResponseAlg, oauthClient.IdTokenEncryptedResponseAlg, oauthClient.IdTokenEncryptedResponseEnc)); }
protected async Task SendLogoutToken(OpenIdClient openIdClient, string sessionId, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(openIdClient.BackChannelLogoutUri)) { return; } var currentDateTime = DateTime.UtcNow; var events = new JObject { { "http://schemas.openid.net/event/backchannel-logout", new JObject() } }; var jwsPayload = new JwsPayload { { Jwt.Constants.OAuthClaims.Issuer, Request.GetAbsoluteUriWithVirtualPath() }, { Jwt.Constants.UserClaims.Subject, User.Claims.First(c => c.Type == ClaimTypes.NameIdentifier).Value }, { Jwt.Constants.OAuthClaims.Audiences, openIdClient.ClientId }, { Jwt.Constants.OAuthClaims.Iat, currentDateTime.ConvertToUnixTimestamp() }, { Jwt.Constants.OAuthClaims.Jti, Guid.NewGuid().ToString() }, { Jwt.Constants.OAuthClaims.Events, events } }; if (openIdClient.BackChannelLogoutSessionRequired) { jwsPayload.Add(Jwt.Constants.OAuthClaims.Sid, sessionId); } var logoutToken = await _jwtBuilder.Sign(jwsPayload, openIdClient.TokenSignedResponseAlg, cancellationToken); using (var httpClient = _httpClientFactory.GetHttpClient()) { var body = new FormUrlEncodedContent(new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("logout_token", logoutToken) }); var request = new HttpRequestMessage { Method = HttpMethod.Post, Content = body, RequestUri = new Uri(openIdClient.BackChannelLogoutUri) }; await httpClient.SendAsync(request); } }
public async Task WhenBuildJwsToken(string clientId, string algName, Table table) { clientId = ParseValue(clientId).ToString(); var jwsPayload = new JwsPayload(); foreach (var record in table.Rows) { jwsPayload.Add(record["Key"].ToString(), record["Value"].ToString()); } var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var clientRepository = (IOAuthClientQueryRepository)_factory.Server.Host.Services.GetService(typeof(IOAuthClientQueryRepository)); var oauthClient = await clientRepository.FindOAuthClientById(clientId, CancellationToken.None); var jsonWebKey = oauthClient.JsonWebKeys.First(f => f.Use == Usages.SIG && f.Alg == algName); var requestParameter = jwtBuilder.Sign(jwsPayload, jsonWebKey, jsonWebKey.Alg); _scenarioContext.Set(requestParameter, "requestParameter"); }
public static void EnrichWithClaimsParameter(JwsPayload payload, IEnumerable <AuthorizationRequestClaimParameter> requestedClaims, OAuthUser user, DateTime?authDateTime, AuthorizationRequestClaimTypes claimType = AuthorizationRequestClaimTypes.IdToken) { if (requestedClaims != null) { foreach (var claim in requestedClaims.Where(c => c.Type == claimType)) { if (USER_CLAIMS.Contains(claim.Name)) { payload.TryAdd(claim.Name, user.Claims.First(c => c.Key == claim.Name).Value); } else { if (claim.Name == OAuthClaims.AuthenticationTime && authDateTime != null) { payload.Add(OAuthClaims.AuthenticationTime, authDateTime.Value.ConvertToUnixTimestamp()); } } } } }
public virtual void EnrichWithClaimsParameter(JwsPayload payload, IEnumerable <AuthorizationRequestClaimParameter> requestedClaims, OAuthUser user = null, DateTime?authDateTime = null, AuthorizationRequestClaimTypes claimType = AuthorizationRequestClaimTypes.IdToken) { if (requestedClaims != null) { foreach (var claim in requestedClaims.Where(c => c.Type == claimType)) { if (AllUserClaims.Contains(claim.Name) && user != null) { payload.AddOrReplace(user.Claims.First(c => c.Type == claim.Name)); } else { if (claim.Name == OAuthClaims.AuthenticationTime && authDateTime != null) { payload.Add(OAuthClaims.AuthenticationTime, authDateTime.Value.ConvertToUnixTimestamp()); } } } } }
public void WhenBuildJWS(string kid, string jwksName, string name, Table table) { var jwks = _scenarioContext.Get <List <JsonWebKey> >(jwksName); kid = ParseValue(kid).ToString(); name = ParseValue(name).ToString(); var jwk = jwks.First(j => j.Kid == kid); var jwsPayload = new JwsPayload(); foreach (var row in table.Rows) { var key = row["Key"]; var value = ParseValue(row["Value"]); jwsPayload.Add(key, value); } var jwtBuilder = (IJwtBuilder)_factory.Server.Host.Services.GetService(typeof(IJwtBuilder)); var jws = jwtBuilder.Sign(jwsPayload, jwk); _scenarioContext.Set(jws, name); }
public static void EnrichWithScopeParameter(JwsPayload payload, IEnumerable <OAuthScope> scopes, OAuthUser user, string subject) { if (scopes != null) { foreach (var scope in scopes) { foreach (var scopeClaim in scope.Claims) { if (scopeClaim.ClaimName == UserClaims.Subject) { payload.Add(UserClaims.Subject, subject); } else { var userClaims = user.Claims.Where(c => c.Type == scopeClaim.ClaimName); payload.AddOrReplace(userClaims); } } } } }
public async Task When_Using_TicketId_Grant_Type_And_Require_ResourceOwnerConsent_Then_RequestSubmitted() { // ARRANGE InitializeFakeObjects(); _httpClientFactoryStub.Setup(h => h.GetHttpClient()).Returns(_server.Client); var jwsPayload = new JwsPayload(); jwsPayload.Add("iss", "http://server.example.com"); jwsPayload.Add("sub", "248289761001"); jwsPayload.Add("role", new[] { "bad_role" }); jwsPayload.Add("aud", "s6BhdRkqt3"); jwsPayload.Add("nonce", "n-0S6_WzA2Mj"); jwsPayload.Add("exp", "1311281970"); jwsPayload.Add("iat", "1311280970"); var jwt = _jwsGenerator.Generate(jwsPayload, JwsAlg.RS256, _server.SharedCtx.SignatureKey); // ACT var result = await _clientAuthSelector.UseClientSecretPostAuth("resource_server", "resource_server") // Get PAT. .UseClientCredentials("uma_protection", "uma_authorization") .ResolveAsync(baseUrl + "/.well-known/uma2-configuration"); var resource = await _resourceSetClient.AddByResolution(new PostResourceSet // Add ressource. { Name = "name", Scopes = new List <string> { "read", "write", "execute" }, AcceptPendingRequest = true }, baseUrl + "/.well-known/uma2-configuration", result.Content.AccessToken); var addPolicy = await _policyClient.AddByResolution(new PostPolicy // Add an authorization policy. { Scopes = new List <string> { "read" }, ClientIdsAllowed = new List <string> { "resource_server" }, Claims = new List <PostClaim> { new PostClaim { Type = "sub", Value = "248289761001" }, new PostClaim { Type = "role", Value = "administrator" } }, ResourceSetIds = new List <string> { resource.Content.Id } }, baseUrl + "/.well-known/uma2-configuration", result.Content.AccessToken); var ticket = await _permissionClient.AddByResolution(new PostPermission // Add permission & retrieve a ticket id. { ResourceSetId = resource.Content.Id, Scopes = new List <string> { "read" } }, baseUrl + "/.well-known/uma2-configuration", "header"); var token = await _clientAuthSelector.UseNoAuthentication() .UseTicketId(ticket.Content.TicketId, jwt) .ResolveAsync(baseUrl + "/.well-known/uma2-configuration").ConfigureAwait(false); // ASSERTS. Assert.True(token.ContainsError); Assert.Equal("not_authorized", token.Error.Error); var detail = JObject.FromObject(token.Error.ErrorDetails.First()); Assert.NotNull(detail); Assert.Equal("RequestSubmitted", detail["status"].ToString()); Assert.Equal("a request has been submitted", detail["details"].ToString()); }
public async Task When_Passing_Not_Valid_Roles_InStringArray_Then_NotAuthorized_Is_Returned() { // ARRANGE const string configurationUrl = "http://localhost/configuration"; InitializeFakeObjects(); var ticket = new Ticket { ClientId = "client_id", Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicy = new Policy { Rules = new List <PolicyRule> { new PolicyRule { ClientIdsAllowed = new List <string> { "client_id" }, Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "role", Value = "role1" }, new Claim { Type = "role", Value = "role2" } } } } }; var claimTokenParameters = new List <ClaimTokenParameter> { new ClaimTokenParameter { Format = "http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken", Token = "token" } }; _parametersProviderStub.Setup(p => p.GetOpenIdConfigurationUrl()) .Returns(configurationUrl); var payload = new JwsPayload(); payload.Add("role", new string[] { "role3" }); _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>())) .Returns(Task.FromResult(payload)); // ACT var result = await _basicAuthorizationPolicy.Execute(ticket, authorizationPolicy, claimTokenParameters); // ASSERT Assert.True(result.Type == AuthorizationPolicyResultEnum.NotAuthorized); }
private async Task <IActionResult> Common(JObject content, CancellationToken cancellationToken) { try { var accessToken = ExtractAccessToken(content); var jwsPayload = await Extract(accessToken, cancellationToken); if (jwsPayload == null) { throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.BAD_TOKEN); } var subject = jwsPayload.GetSub(); var scopes = jwsPayload.GetScopes(); var audiences = jwsPayload.GetAudiences(); var claims = jwsPayload.GetClaimsFromAccessToken(AuthorizationRequestClaimTypes.UserInfo); var authTime = jwsPayload.GetAuthTime(); var user = await _oauthUserRepository.FindOAuthUserByLogin(subject, cancellationToken); if (user == null) { return(new UnauthorizedResult()); } var filteredClients = await _oauthClientRepository.FindOAuthClientByIds(audiences, cancellationToken); if (!filteredClients.Any()) { throw new OAuthException(ErrorCodes.INVALID_CLIENT, ErrorMessages.INVALID_AUDIENCE); } var oauthClient = (OpenIdClient)filteredClients.First(); if (!user.HasOpenIDConsent(oauthClient.ClientId, scopes, claims, AuthorizationRequestClaimTypes.UserInfo)) { throw new OAuthException(ErrorCodes.INVALID_REQUEST, ErrorMessages.NO_CONSENT); } var token = await _tokenRepository.Get(accessToken, cancellationToken); if (token == null) { _logger.LogError("Cannot get user information because access token has been rejected"); throw new OAuthException(ErrorCodes.INVALID_TOKEN, OAuth.ErrorMessages.ACCESS_TOKEN_REJECTED); } var oauthScopes = await _oauthScopeRepository.FindOAuthScopesByNames(scopes, cancellationToken); var payload = new JwsPayload(); IdTokenBuilder.EnrichWithScopeParameter(payload, oauthScopes, user, subject); _claimsJwsPayloadEnricher.EnrichWithClaimsParameter(payload, claims, user, authTime, AuthorizationRequestClaimTypes.UserInfo); foreach (var claimsSource in _claimsSources) { await claimsSource.Enrich(payload, oauthClient, cancellationToken); } string contentType = "application/json"; var result = JsonConvert.SerializeObject(payload).ToString(); if (!string.IsNullOrWhiteSpace(oauthClient.UserInfoSignedResponseAlg)) { payload.Add(Jwt.Constants.OAuthClaims.Issuer, Request.GetAbsoluteUriWithVirtualPath()); payload.Add(Jwt.Constants.OAuthClaims.Audiences, new string[] { token.ClientId }); result = await _jwtBuilder.BuildClientToken(oauthClient, payload, oauthClient.UserInfoSignedResponseAlg, oauthClient.UserInfoEncryptedResponseAlg, oauthClient.UserInfoEncryptedResponseEnc, cancellationToken); contentType = "application/jwt"; } return(new ContentResult { Content = result, ContentType = contentType }); } catch (OAuthException ex) { var jObj = new JObject { { ErrorResponseParameters.Error, ex.Code }, { ErrorResponseParameters.ErrorDescription, ex.Message } }; return(new ContentResult { Content = jObj.ToString(), ContentType = "application/json", StatusCode = (int)HttpStatusCode.BadRequest }); } }
public async Task When_Using_TicketId_Grant_Type_Then_AccessToken_Is_Returned() { // ARRANGE InitializeFakeObjects(); _httpClientFactoryStub.Setup(h => h.GetHttpClient()).Returns(_server.Client); var jwsPayload = new JwsPayload(); jwsPayload.Add("iss", "http://server.example.com"); jwsPayload.Add("sub", "248289761001"); jwsPayload.Add("aud", "s6BhdRkqt3"); jwsPayload.Add("nonce", "n-0S6_WzA2Mj"); jwsPayload.Add("exp", "1311281970"); jwsPayload.Add("iat", "1311280970"); var jwt = _jwsGenerator.Generate(jwsPayload, JwsAlg.RS256, _server.SharedCtx.SignatureKey); // ACT var result = await _clientAuthSelector.UseClientSecretPostAuth("resource_server", "resource_server") // Get PAT. .UseClientCredentials("uma_protection", "uma_authorization") .ResolveAsync(baseUrl + "/.well-known/uma2-configuration"); var resource = await _resourceSetClient.AddByResolution(new PostResourceSet // Add ressource. { Name = "name", Scopes = new List <string> { "read", "write", "execute" } }, baseUrl + "/.well-known/uma2-configuration", result.Content.AccessToken); var addPolicy = await _policyClient.AddByResolution(new PostPolicy // Add an authorization policy. { Rules = new List <PostPolicyRule> { new PostPolicyRule { IsResourceOwnerConsentNeeded = false, Scopes = new List <string> { "read" }, ClientIdsAllowed = new List <string> { "resource_server" }, Claims = new List <PostClaim> { new PostClaim { Type = "sub", Value = "248289761001" } } } }, ResourceSetIds = new List <string> { resource.Content.Id } }, baseUrl + "/.well-known/uma2-configuration", result.Content.AccessToken); var ticket = await _permissionClient.AddByResolution(new PostPermission // Add permission & retrieve a ticket id. { ResourceSetId = resource.Content.Id, Scopes = new List <string> { "read" } }, baseUrl + "/.well-known/uma2-configuration", "header"); var token = await _clientAuthSelector.UseClientSecretPostAuth("resource_server", "resource_server") // Try to get the access token via "ticket_id" grant-type. .UseTicketId(ticket.Content.TicketId, jwt) .ResolveAsync(baseUrl + "/.well-known/uma2-configuration"); // ASSERTS. Assert.NotNull(token); }
public async Task When_Passing_Not_Valid_Roles_InStringArray_Then_NotAuthorized_Is_Returned() { // ARRANGE InitializeFakeObjects(); var ticket = new TicketLineParameter { Scopes = new List <string> { "read", "create", "update" } }; var authorizationPolicies = new List <Policy> { new Policy { Scopes = new List <string> { "read", "create", "update" }, Claims = new List <Claim> { new Claim { Type = "role", Value = "role1" }, new Claim { Type = "role", Value = "role2" } } } }; var claimTokenParameter = new ClaimTokenParameter { Format = "http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken", Token = "token" }; var payload = new JwsPayload(); payload.Add("role", new string[] { "role3" }); _jwtTokenParserStub.Setup(j => j.UnSign(It.IsAny <string>(), It.IsAny <string>())) .Returns(Task.FromResult(payload)); // ACT var result = await _basicAuthorizationPolicy.Execute("openid", new ResourceSet { Id = "resourceid", AuthPolicies = authorizationPolicies }, ticket, claimTokenParameter); // ASSERT Assert.False(result.IsValid); var error = result.AuthorizationPoliciesResult.First(); Assert.True(error.Type == AuthorizationPolicyResultEnum.NeedInfo); }
private async Task FillInIdentityTokenClaims( JwsPayload jwsPayload, AuthorizationParameter authorizationParameter, List <ClaimParameter> claimParameters, ClaimsPrincipal claimsPrincipal) { var nonce = authorizationParameter.Nonce; var state = authorizationParameter.State; var clientId = authorizationParameter.ClientId; var maxAge = authorizationParameter.MaxAge; var issuerClaimParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Issuer); var audiencesClaimParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Audiences); var expirationTimeClaimParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.ExpirationTime); var issuedAtTimeClaimParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Iat); var authenticationTimeParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.AuthenticationTime); var nonceParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Nonce); var acrParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Acr); var amrParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Amr); var azpParameter = claimParameters.FirstOrDefault(c => c.Name == Jwt.Constants.StandardClaimNames.Azp); var timeKeyValuePair = await GetExpirationAndIssuedTime(); var issuerName = await _configurationService.GetIssuerNameAsync(); var audiences = new List <string>(); var expirationInSeconds = timeKeyValuePair.Key; var issuedAtTime = timeKeyValuePair.Value; var acrValues = Constants.StandardArcParameterNames.OpenIdCustomAuthLevel + ".password=1"; var amr = new [] { "password" }; var azp = string.Empty; var clients = await _clientRepository.GetAllAsync(); foreach (var client in clients) { var isClientSupportIdTokenResponseType = _clientValidator.CheckResponseTypes(client, ResponseType.id_token); if (isClientSupportIdTokenResponseType || client.ClientId == authorizationParameter.ClientId) { audiences.Add(client.ClientId); } } // The identity token can be reused by the simple identity server. if (!string.IsNullOrWhiteSpace(issuerName)) { audiences.Add(issuerName); } var authenticationInstant = claimsPrincipal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.AuthenticationInstant); var authenticationInstantValue = authenticationInstant == null ? string.Empty : authenticationInstant.Value; if (issuerClaimParameter != null) { var issuerIsValid = ValidateClaimValue(issuerName, issuerClaimParameter); if (!issuerIsValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Issuer), state); } } if (audiences.Count() > 1 || audiences.Count() == 1 && audiences.First() != clientId) { azp = clientId; } if (audiencesClaimParameter != null) { var audiencesIsValid = ValidateClaimValues(audiences.ToArray(), audiencesClaimParameter); if (!audiencesIsValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Audiences), state); } } if (expirationTimeClaimParameter != null) { var expirationInSecondsIsValid = ValidateClaimValue(expirationInSeconds.ToString(CultureInfo.InvariantCulture), expirationTimeClaimParameter); if (!expirationInSecondsIsValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.ExpirationTime), state); } } if (issuedAtTimeClaimParameter != null) { var issuedAtTimeIsValid = ValidateClaimValue(issuedAtTime.ToString(), issuedAtTimeClaimParameter); if (!issuedAtTimeIsValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Iat), state); } } if (authenticationTimeParameter != null) { var isAuthenticationTimeValid = ValidateClaimValue(authenticationInstantValue, authenticationTimeParameter); if (!isAuthenticationTimeValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.AuthenticationTime), state); } } if (acrParameter != null) { var isAcrParameterValid = ValidateClaimValue(acrValues, acrParameter); if (!isAcrParameterValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Acr), state); } } if (nonceParameter != null) { var isNonceParameterValid = ValidateClaimValue(nonce, nonceParameter); if (!isNonceParameterValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Nonce), state); } } if (amrParameter != null) { var isAmrParameterValid = ValidateClaimValues(amr, amrParameter); if (!isAmrParameterValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Amr), state); } } // Fill-in the AZP parameter if (azpParameter != null) { var isAzpParameterValid = ValidateClaimValue(azp, azpParameter); if (!isAzpParameterValid) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheClaimIsNotValid, Jwt.Constants.StandardClaimNames.Azp), state); } } jwsPayload.Add(Jwt.Constants.StandardClaimNames.Issuer, issuerName); jwsPayload.Add(Jwt.Constants.StandardClaimNames.Audiences, audiences.ToArray()); jwsPayload.Add(Jwt.Constants.StandardClaimNames.ExpirationTime, expirationInSeconds); jwsPayload.Add(Jwt.Constants.StandardClaimNames.Iat, issuedAtTime); // Set the auth_time if it's requested as an essential claim OR the max_age request is specified if (((authenticationTimeParameter != null && authenticationTimeParameter.Essential) || !maxAge.Equals(default(double))) && !string.IsNullOrWhiteSpace(authenticationInstantValue)) { jwsPayload.Add(Jwt.Constants.StandardClaimNames.AuthenticationTime, double.Parse(authenticationInstantValue)); } if (!string.IsNullOrWhiteSpace(nonce)) { jwsPayload.Add(Jwt.Constants.StandardClaimNames.Nonce, nonce); } jwsPayload.Add(Jwt.Constants.StandardClaimNames.Acr, acrValues); jwsPayload.Add(Jwt.Constants.StandardClaimNames.Amr, amr); if (!string.IsNullOrWhiteSpace(azp)) { jwsPayload.Add(Jwt.Constants.StandardClaimNames.Azp, azp); } }