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);
        }
示例#2
0
        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");
        }
示例#3
0
 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());
 }
示例#4
0
        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);
        }
示例#6
0
        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());
            }
        }
示例#8
0
        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);
        }
示例#9
0
        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();
        }
示例#11
0
        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);
                }
            }
        }
示例#12
0
        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());
         }
     }
 }
示例#14
0
        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);
        }
示例#15
0
        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());
                }
            }
        }
示例#16
0
        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));
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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");
        }
示例#19
0
 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());
                 }
             }
         }
     }
 }
示例#21
0
        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);
        }
示例#22
0
 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);
                 }
             }
         }
     }
 }
示例#23
0
        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());
        }
示例#24
0
        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);
        }
示例#27
0
        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);
        }
示例#28
0
        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);
            }
        }