示例#1
0
        /// <summary>
        /// Returns claims for an identity token
        /// </summary>
        /// <param name="subject">The subject</param>
        /// <param name="client">The client</param>
        /// <param name="scopes">The requested scopes</param>
        /// <param name="includeAllIdentityClaims">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>
        /// <param name="request">The raw request</param>
        /// <returns>
        /// Claims for the identity token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable <Scope> scopes, bool includeAllIdentityClaims, ValidatedRequest request)
        {
            Logger.Info("Getting claims for identity token for subject: " + subject.GetSubjectId());

            var outputClaims = new List <Claim>(GetStandardSubjectClaims(subject));

            outputClaims.AddRange(GetOptionalClaims(subject));

            var additionalClaims = new List <string>();

            // if a include all claims rule exists, call the user service without a claims filter
            if (scopes.IncludesAllClaimsForUserRule(ScopeType.Identity))
            {
                Logger.Info("All claims rule found - emitting all claims for user.");

                var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderIdentityToken);

                await _users.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }

                return(outputClaims);
            }

            // fetch all identity claims that need to go into the id token
            foreach (var scope in scopes)
            {
                if (scope.Type == ScopeType.Identity)
                {
                    foreach (var scopeClaim in scope.Claims)
                    {
                        if (includeAllIdentityClaims || scopeClaim.AlwaysIncludeInIdToken)
                        {
                            additionalClaims.Add(scopeClaim.Name);
                        }
                    }
                }
            }

            if (additionalClaims.Count > 0)
            {
                var context = new ProfileDataRequestContext(
                    subject,
                    client,
                    Constants.ProfileDataCallers.ClaimsProviderIdentityToken,
                    additionalClaims);

                await _users.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }
            }

            return(outputClaims);
        }
        protected override ActionResult ShowConsent(ValidatedRequest validatedRequest)
        {
            Tracing.Information("OIDC Consent screen");

            return View("Consent", new OidcViewModel(validatedRequest));
        }
        /// <summary>
        /// Returns claims for an identity token
        /// </summary>
        /// <param name="subject">The subject</param>
        /// <param name="resources">The requested resources</param>
        /// <param name="includeAllIdentityClaims">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>
        /// <param name="request">The raw request</param>
        /// <returns>
        /// Claims for the identity token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, bool includeAllIdentityClaims, ValidatedRequest request)
        {
            Logger.LogDebug("Getting claims for identity token for subject: {subject} and client: {clientId}",
                            subject.GetSubjectId(),
                            request.Client.ClientId);

            var outputClaims = new List <Claim>(GetStandardSubjectClaims(subject));

            outputClaims.AddRange(GetOptionalClaims(subject));

            // fetch all identity claims that need to go into the id token
            if (includeAllIdentityClaims || request.Client.AlwaysIncludeUserClaimsInIdToken)
            {
                var additionalClaimTypes = new List <string>();

                foreach (var identityResource in resources.IdentityResources)
                {
                    foreach (var userClaim in identityResource.UserClaims)
                    {
                        additionalClaimTypes.Add(userClaim);
                    }
                }

                // filter so we don't ask for claim types that we will eventually filter out
                additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();

                var context = new ProfileDataRequestContext(
                    subject,
                    request.Client,
                    IdentityServerConstants.ProfileDataCallers.ClaimsProviderIdentityToken,
                    additionalClaimTypes);
                context.RequestedResources = resources;

                await Profile.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }
            }
            else
            {
                Logger.LogDebug("In addition to an id_token, an access_token was requested. No claims other than sub are included in the id_token. To obtain more user claims, either use the user info endpoint or set AlwaysIncludeUserClaimsInIdToken on the client configuration.");
            }

            return(outputClaims);
        }
示例#4
0
        /// <summary>
        /// Returns claims for an identity token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="client">The client.</param>
        /// <param name="scopes">The requested scopes.</param>
        /// <param name="request">The raw request.</param>
        /// <returns>
        /// Claims for the access token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable <Scope> scopes, ValidatedRequest request)
        {
            // add client_id
            var outputClaims = new List <Claim>
            {
                new Claim(Constants.ClaimTypes.ClientId, client.ClientId),
            };

            // check for client claims
            if (client.Claims != null && client.Claims.Any())
            {
                if (subject == null || client.AlwaysSendClientClaims)
                {
                    foreach (var claim in client.Claims)
                    {
                        var claimType = claim.Type;

                        if (client.PrefixClientClaims)
                        {
                            claimType = "client_" + claimType;
                        }

                        outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));
                    }
                }
            }

            // add scopes
            foreach (var scope in scopes)
            {
                outputClaims.Add(new Claim(Constants.ClaimTypes.Scope, scope.Name));
            }

            // a user is involved
            if (subject != null)
            {
                outputClaims.AddRange(GetStandardSubjectClaims(subject));
                outputClaims.AddRange(GetOptionalClaims(subject));

                // if a include all claims rule exists, call the user service without a claims filter
                if (scopes.IncludesAllClaimsForUserRule(ScopeType.Resource) || scopes.IncludesAllClaimsForUserRule(ScopeType.Identity))
                {
                    var context = new ProfileDataRequestContext(
                        subject,
                        client,
                        Constants.ProfileDataCallers.ClaimsProviderAccessToken);

                    await _users.GetProfileDataAsync(context);

                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }

                    return(outputClaims);
                }


                // fetch all resource claims that need to go into the access token
                var additionalClaims = new List <string>();
                foreach (var scope in scopes)
                {
                    if (scope.Type == ScopeType.Resource)
                    {
                        if (scope.Claims != null)
                        {
                            foreach (var scopeClaim in scope.Claims)
                            {
                                additionalClaims.Add(scopeClaim.Name);
                            }
                        }
                    }
                }

                if (additionalClaims.Count > 0)
                {
                    var context = new ProfileDataRequestContext(
                        subject,
                        client,
                        Constants.ProfileDataCallers.ClaimsProviderAccessToken,
                        additionalClaims.Distinct());

                    await _users.GetProfileDataAsync(context);

                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }
                }
            }

            return(outputClaims);
        }
示例#5
0
        public ValidatedRequest Validate(Application application, AuthorizeRequest request)
        {
            // If the request fails due to a missing, invalid, or mismatching
            // redirection URI, or if the client identifier is missing or invalid,
            // the authorization server SHOULD inform the resource owner of the
            // error and MUST NOT automatically redirect the user-agent to the
            // invalid redirection URI.

            var validatedRequest = new ValidatedRequest();

            // validate request model binding
            if (request == null)
            {
                throw new AuthorizeRequestResourceOwnerException("Invalid request parameters.");
            }

            validatedRequest.Application = application;
            Tracing.InformationFormat("OAuth2 application: {0} ({1})",
                                      validatedRequest.Application.Name,
                                      validatedRequest.Application.Namespace);

            validatedRequest.ShowRememberConsent = application.AllowRememberConsentDecision;

            // make sure redirect uri is present
            if (string.IsNullOrWhiteSpace(request.redirect_uri))
            {
                throw new AuthorizeRequestResourceOwnerException("Missing redirect URI");
            }

            // validate client
            if (string.IsNullOrWhiteSpace(request.client_id))
            {
                throw new AuthorizeRequestResourceOwnerException("Missing client identifier");
            }


            var client = _clientManager.Get(request.client_id);

            if (client == null)
            {
                throw new AuthorizeRequestResourceOwnerException("Invalid client: " + request.client_id);
            }

            validatedRequest.Client = client;
            Tracing.InformationFormat("Client: {0} ({1})",
                                      validatedRequest.Client.Name,
                                      validatedRequest.Client.ClientId);

            // make sure redirect_uri is a valid uri, and in case of http is over ssl
            Uri redirectUri;

            if (Uri.TryCreate(request.redirect_uri, UriKind.Absolute, out redirectUri))
            {
                if (redirectUri.Scheme == Uri.UriSchemeHttp)
                {
                    throw new AuthorizeRequestClientException(
                              "Redirect URI not over SSL : " + request.redirect_uri,
                              new Uri(request.redirect_uri),
                              OAuthConstants.Errors.InvalidRequest,
                              string.Empty,
                              validatedRequest.State);
                }

                // make sure redirect uri is registered with client
                var validUri = validatedRequest.Client.RedirectUris.Get(request.redirect_uri);

                if (validUri == null)
                {
                    throw new AuthorizeRequestResourceOwnerException("Invalid redirect URI: " + request.redirect_uri);
                }

                validatedRequest.RedirectUri = validUri;
                Tracing.InformationFormat("Redirect URI: {0} ({1})",
                                          validatedRequest.RedirectUri.Uri,
                                          validatedRequest.RedirectUri.Description);
            }
            else
            {
                var message = "Invalid redirect URI: " + request.redirect_uri;
                Tracing.Error(message);

                throw new AuthorizeRequestResourceOwnerException("Invalid redirect URI: " + request.redirect_uri);
            }

            // check state
            if (!string.IsNullOrWhiteSpace(request.state))
            {
                validatedRequest.State = request.state;
                Tracing.Information("State: " + validatedRequest.State);
            }
            else
            {
                Tracing.Information("No state supplied.");
            }

            // validate response type
            if (String.IsNullOrWhiteSpace(request.response_type))
            {
                throw new AuthorizeRequestClientException(
                          "response_type is null or empty",
                          new Uri(validatedRequest.RedirectUri.Uri),
                          OAuthConstants.Errors.InvalidRequest,
                          string.Empty,
                          validatedRequest.State);
            }

            // check response type (only code and token are supported)
            if (!request.response_type.Equals(OAuthConstants.ResponseTypes.Token, StringComparison.Ordinal) &&
                !request.response_type.Equals(OAuthConstants.ResponseTypes.Code, StringComparison.Ordinal))
            {
                throw new AuthorizeRequestClientException(
                          "response_type is not token or code: " + request.response_type,
                          new Uri(validatedRequest.RedirectUri.Uri),
                          OAuthConstants.Errors.UnsupportedResponseType,
                          string.Empty,
                          validatedRequest.State);
            }

            validatedRequest.ResponseType = request.response_type;
            Tracing.Information("Response type: " + validatedRequest.ResponseType);

            if (request.response_type == OAuthConstants.ResponseTypes.Code)
            {
                ValidateCodeResponseType(validatedRequest, request);
            }
            else if (request.response_type == OAuthConstants.ResponseTypes.Token)
            {
                ValidateTokenResponseType(validatedRequest, request);
            }
            else
            {
                throw new AuthorizeRequestClientException(
                          "Invalid response_type: " + request.response_type,
                          new Uri(validatedRequest.RedirectUri.Uri),
                          OAuthConstants.Errors.UnsupportedResponseType,
                          request.response_type,
                          validatedRequest.State);
            }

            ValidateScopes(request, validatedRequest);

            // TODO: fix based upon past "remember me" settings
            validatedRequest.ShowConsent = client.RequireConsent || application.RequireConsent;

            Tracing.Information("Authorize request validation successful.");
            return(validatedRequest);
        }
        /// <summary>
        /// Returns claims for an identity token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="resources">The requested resources</param>
        /// <param name="request">The raw request.</param>
        /// <returns>
        /// Claims for the access token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Resources resources, ValidatedRequest request)
        {
            Logger.LogDebug("Getting claims for access token for client: {clientId}", request.Client.ClientId);

            // add client_id
            var outputClaims = new List <Claim>
            {
                new Claim(JwtClaimTypes.ClientId, request.Client.ClientId)
            };

            // check for client claims
            if (request.ClientClaims != null && request.ClientClaims.Any())
            {
                if (subject == null || request.Client.AlwaysSendClientClaims)
                {
                    foreach (var claim in request.ClientClaims)
                    {
                        var claimType = claim.Type;

                        if (request.Client.ClientClaimsPrefix.IsPresent())
                        {
                            claimType = request.Client.ClientClaimsPrefix + claimType;
                        }

                        outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));
                    }
                }
            }

            // add scopes
            foreach (var scope in resources.IdentityResources)
            {
                outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope.Name));
            }
            foreach (var scope in resources.ApiResources.SelectMany(x => x.Scopes))
            {
                outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope.Name));
            }

            // a user is involved
            if (subject != null)
            {
                if (resources.OfflineAccess)
                {
                    outputClaims.Add(new Claim(JwtClaimTypes.Scope, IdentityServerConstants.StandardScopes.OfflineAccess));
                }

                Logger.LogDebug("Getting claims for access token for subject: {subject}", subject.GetSubjectId());

                outputClaims.AddRange(GetStandardSubjectClaims(subject));
                outputClaims.AddRange(GetOptionalClaims(subject));

                // fetch all resource claims that need to go into the access token
                var additionalClaimTypes = new List <string>();
                foreach (var api in resources.ApiResources)
                {
                    // add claims configured on api resource
                    if (api.UserClaims != null)
                    {
                        foreach (var claim in api.UserClaims)
                        {
                            additionalClaimTypes.Add(claim);
                        }
                    }

                    // add claims configured on scope
                    foreach (var scope in api.Scopes)
                    {
                        if (scope.UserClaims != null)
                        {
                            foreach (var claim in scope.UserClaims)
                            {
                                additionalClaimTypes.Add(claim);
                            }
                        }
                    }
                }

                // filter so we don't ask for claim types that we will eventually filter out
                additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();

                var context = new ProfileDataRequestContext(
                    subject,
                    request.Client,
                    IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken,
                    additionalClaimTypes.Distinct());
                context.RequestedResources = resources;

                await Profile.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }
            }

            return(outputClaims);
        }
示例#7
0
        public override async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject,
                                                                                    ResourceValidationResult resourceResult, ValidatedRequest request)
        {
            if (_scopedOverrideRawScopeValues.IsOverride)
            {
                var scopes = new HashSet <ParsedScopeValue>();
                foreach (var s in _scopedOverrideRawScopeValues.Scopes)
                {
                    scopes.Add((new ParsedScopeValue(s)));
                }
                if (resourceResult.Resources.OfflineAccess)
                {
                    scopes.Add((new ParsedScopeValue(IdentityServerConstants.StandardScopes.OfflineAccess)));
                }

                resourceResult.ParsedScopes = scopes;
            }



            var claims = await base.GetAccessTokenClaimsAsync(subject, resourceResult, request);

            var clientExtra = request.Client as ClientExtra;

            if (!clientExtra.IncludeClientId)
            {
                claims = from claim in claims
                         where claim.Type != JwtClaimTypes.ClientId
                         select claim;
            }

            /*
             * if (!clientExtra.IncludeAmr)
             * {
             *  var queryAmr = from claim in claims
             *                 where claim.Type == JwtClaimTypes.AuthenticationMethod
             *                 select claim;
             *  if (queryAmr.Count() == 1)
             *  {
             *      // only meant to remove the single one that IDS4 added.
             *      claims = from claim in claims
             *               where claim.Type != JwtClaimTypes.AuthenticationMethod
             *              select claim;
             *  }
             * }*/
            var subjectClaim = (from claim in claims
                                where claim.Type == JwtClaimTypes.Subject
                                select claim).FirstOrDefault();

            if (subjectClaim != null && subjectClaim.Value == Constants.ReservedSubject)
            {
                claims = from claim in claims
                         where claim.Type != JwtClaimTypes.Subject
                         select claim;
            }
            return(claims);
        }
        /// <summary>
        /// Returns claims for an identity token
        /// </summary>
        /// <param name="subject">The subject</param>
        /// <param name="client">The client</param>
        /// <param name="identityResources">The requested scopes</param>
        /// <param name="includeAllIdentityClaims">Specifies if all claims should be included in the token, or if the userinfo endpoint can be used to retrieve them</param>
        /// <param name="request">The raw request</param>
        /// <returns>
        /// Claims for the identity token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetIdentityTokenClaimsAsync(ClaimsPrincipal subject, Client client, Resources resources, bool includeAllIdentityClaims, ValidatedRequest request)
        {
            _logger.LogDebug("Getting claims for identity token for subject: {subject} and client: {clientId}", subject.GetSubjectId(), client.ClientId);

            var outputClaims = new List <Claim>(GetStandardSubjectClaims(subject));

            outputClaims.AddRange(GetOptionalClaims(subject));

            // fetch all identity claims that need to go into the id token
            if (includeAllIdentityClaims || client.AlwaysIncludeUserClaimsInIdToken)
            {
                var additionalClaims = new List <string>();

                foreach (var identityResource in resources.IdentityResources)
                {
                    foreach (var userClaim in identityResource.UserClaims)
                    {
                        additionalClaims.Add(userClaim);
                    }
                }

                if (additionalClaims.Count > 0)
                {
                    var context = new ProfileDataRequestContext(
                        subject,
                        client,
                        IdentityServerConstants.ProfileDataCallers.ClaimsProviderIdentityToken,
                        additionalClaims);

                    await _profile.GetProfileDataAsync(context);

                    var claims = FilterProtocolClaims(context.IssuedClaims);
                    if (claims != null)
                    {
                        outputClaims.AddRange(claims);
                    }
                }
            }

            return(outputClaims);
        }
        public override async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject,
                                                                                    Client client, Resources resources, ValidatedRequest request)
        {
            var arbitraryClaimsCheck = request.Raw.ContainsAny(RequiredArbitraryClaimsArgument);
            var arbitraryScopesCheck = request.Raw.ContainsAny(RequiredArbitraryScopes);

            if (!arbitraryClaimsCheck && !arbitraryScopesCheck)
            {
                var missing = string.Join(",", RequiredArbitraryClaimsArgument.ToArray());
                missing += ",";
                missing += string.Join(",", RequiredArbitraryScopes.ToArray());
                var ex = new Exception(string.Format("RequiredArgument failed need the following [{0}]", missing));
                _logger.LogError(LoggingEvents.REQUIRED_ITEMS_MISSING, ex);
                throw ex;
            }
            var          result      = base.GetAccessTokenClaimsAsync(subject, client, resources, request);
            var          rr          = request.Raw.AllKeys.ToDictionary(k => k, k => request.Raw[k]);
            List <Claim> finalClaims = new List <Claim>(result.Result);

            if (arbitraryScopesCheck)
            {
                var newScopes = rr["arbitrary-scopes"].Split(new char[] { ' ', '\t' },
                                                             StringSplitOptions.RemoveEmptyEntries);
                foreach (var scope in newScopes)
                {
                    finalClaims.Add(new Claim("scope", scope));
                }
            }
            Dictionary <string, string> values;

            if (arbitraryClaimsCheck)
            {
                values =
                    JsonConvert.DeserializeObject <Dictionary <string, string> >(rr["arbitrary-claims"]);
                // paranoia check.  In no way can we allow creation which tries to spoof someone elses client_id.

                var query = from value in values
                            where string.Compare(value.Key, "client_id", true) != 0
                            select value;
                var trimmedClaims = query.ToList();
                finalClaims.AddRange(trimmedClaims.Select(value => new Claim(value.Key, value.Value)));
            }
            if (subject != null)
            {
                finalClaims.AddRange(subject.Claims.Where(p2 =>
                                                          finalClaims.All(p1 => p1.Type != p2.Type)));
            }
            // if we find any, than add them to the original and send that back.
            IEnumerable <Claim> claimresults = finalClaims;

            return(claimresults);
        }
        public virtual TokenResponse CreateTokenResponseFromRefreshToken(StoredGrant handle, IStoredGrantManager handleManager)
        {
            var resourceOwner = Principal.Create(
                "OAuth2",
                handle.ResourceOwner.ToClaims().ToArray());

            if (DateTime.UtcNow > handle.Expiration)
            {
                throw new InvalidOperationException("Refresh token has expired.");
            }

            var validatedRequest = new ValidatedRequest
            {
                Client      = handle.Client,
                Application = handle.Application,
                Scopes      = handle.Scopes,
            };

            var response = CreateTokenResponse(validatedRequest, resourceOwner);

            if (handle.CreateRefreshToken)
            {
                StoredGrant refreshTokenHandle;

                if (validatedRequest.Application.AllowSlidingRefreshTokenExpiration)
                {
                    var rememberTimeSpan          = handle.Expiration.Subtract(handle.Created);
                    var newRefreshTokenExpiration = DateTime.UtcNow.Add(rememberTimeSpan);

                    refreshTokenHandle = StoredGrant.CreateRefreshTokenHandle(
                        resourceOwner.GetSubject(),
                        handle.Client,
                        handle.Application,
                        resourceOwner.Claims,
                        handle.Scopes,
                        newRefreshTokenExpiration,
                        createRefreshToken: validatedRequest.Client.AllowRefreshToken && validatedRequest.Application.AllowRefreshToken);
                }
                else
                {
                    refreshTokenHandle = StoredGrant.CreateRefreshTokenHandle(
                        resourceOwner.GetSubject(),
                        handle.Client,
                        handle.Application,
                        resourceOwner.Claims,
                        handle.Scopes,
                        handle.Expiration,
                        createRefreshToken: validatedRequest.Client.AllowRefreshToken && validatedRequest.Application.AllowRefreshToken);
                }

                response.RefreshToken = refreshTokenHandle.GrantId;

                handleManager.Add(refreshTokenHandle);
                handleManager.Delete(handle.GrantId);
            }
            else
            {
                response.RefreshToken = handle.GrantId;
            }
            return(response);
        }
示例#11
0
        /// <summary>
        /// Returns claims for an identity token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="client">The client.</param>
        /// <param name="scopes">The requested scopes.</param>
        /// <param name="request">The raw request.</param>
        /// <returns>
        /// Claims for the access token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable <Scope> scopes, ValidatedRequest request)
        {
            // add client_id
            var outputClaims = new List <Claim>
            {
                new Claim(Constants.ClaimTypes.ClientId, client.ClientId),
            };

            // check for client claims
            return(await ConstructOutputClaims(subject, client, scopes, outputClaims));
        }
        public override async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject, Client client, IEnumerable <Scope> scopes, ValidatedRequest request)
        {
            var claims = await base.GetAccessTokenClaimsAsync(subject, client, scopes, request);

            var newClaims = claims.ToList();

            if (subject != null)
            {
                newClaims.Add(subject.FindFirst("user511id"));
                newClaims.Add(subject.FindFirst("userrole"));
                newClaims.Add(subject.FindFirst("greetingname"));
                newClaims.Add(subject.FindFirst("useremail"));
                newClaims.Add(subject.FindFirst("encrypted511Id"));
                newClaims.Add(subject.FindFirst("userroleid"));
                newClaims.Add(subject.FindFirst("usercountry"));
                newClaims.Add(subject.FindFirst("isvaliduser"));
                newClaims.Add(subject.FindFirst("name"));
            }
            return(newClaims);
        }
示例#13
0
        /// <summary>
        /// Returns claims for an access token.
        /// </summary>
        /// <param name="subject">The subject.</param>
        /// <param name="resourceResult">The validated resource result</param>
        /// <param name="request">The raw request.</param>
        /// <returns>
        /// Claims for the access token
        /// </returns>
        public virtual async Task <IEnumerable <Claim> > GetAccessTokenClaimsAsync(ClaimsPrincipal subject, ResourceValidationResult resourceResult, ValidatedRequest request)
        {
            Logger.LogDebug("Getting claims for access token for client: {clientId}", request.Client.ClientId);

            var outputClaims = new List <Claim>
            {
                new Claim(JwtClaimTypes.ClientId, request.ClientId)
            };

            // log if client ID is overwritten
            if (!string.Equals(request.ClientId, request.Client.ClientId))
            {
                Logger.LogDebug("Client {clientId} is impersonating {impersonatedClientId}", request.Client.ClientId, request.ClientId);
            }

            // check for client claims
            if (request.ClientClaims != null && request.ClientClaims.Any())
            {
                if (subject == null || request.Client.AlwaysSendClientClaims)
                {
                    foreach (var claim in request.ClientClaims)
                    {
                        var claimType = claim.Type;

                        if (request.Client.ClientClaimsPrefix.IsPresent())
                        {
                            claimType = request.Client.ClientClaimsPrefix + claimType;
                        }

                        outputClaims.Add(new Claim(claimType, claim.Value, claim.ValueType));
                    }
                }
            }

            // add scopes (filter offline_access)
            // we use the ScopeValues collection rather than the Resources.Scopes because we support dynamic scope values
            // from the request, so this issues those in the token.
            foreach (var scope in resourceResult.RawScopeValues.Where(x => x != IdentityServerConstants.StandardScopes.OfflineAccess))
            {
                outputClaims.Add(new Claim(JwtClaimTypes.Scope, scope));
            }

            // a user is involved
            if (subject != null)
            {
                if (resourceResult.Resources.OfflineAccess)
                {
                    outputClaims.Add(new Claim(JwtClaimTypes.Scope, IdentityServerConstants.StandardScopes.OfflineAccess));
                }

                Logger.LogDebug("Getting claims for access token for subject: {subject}", subject.GetSubjectId());

                outputClaims.AddRange(GetStandardSubjectClaims(subject));
                outputClaims.AddRange(GetOptionalClaims(subject));

                // fetch all resource claims that need to go into the access token
                var additionalClaimTypes = new List <string>();
                foreach (var api in resourceResult.Resources.ApiResources)
                {
                    // add claims configured on api resource
                    if (api.UserClaims != null)
                    {
                        foreach (var claim in api.UserClaims)
                        {
                            additionalClaimTypes.Add(claim);
                        }
                    }
                }

                foreach (var scope in resourceResult.Resources.ApiScopes)
                {
                    // add claims configured on scopes
                    if (scope.UserClaims != null)
                    {
                        foreach (var claim in scope.UserClaims)
                        {
                            additionalClaimTypes.Add(claim);
                        }
                    }
                }

                // filter so we don't ask for claim types that we will eventually filter out
                additionalClaimTypes = FilterRequestedClaimTypes(additionalClaimTypes).ToList();

                var context = new ProfileDataRequestContext(
                    subject,
                    request.Client,
                    IdentityServerConstants.ProfileDataCallers.ClaimsProviderAccessToken,
                    additionalClaimTypes.Distinct())
                {
                    RequestedResources = resourceResult,
                    ValidatedRequest   = request
                };

                await Profile.GetProfileDataAsync(context);

                var claims = FilterProtocolClaims(context.IssuedClaims);
                if (claims != null)
                {
                    outputClaims.AddRange(claims);
                }
            }

            return(outputClaims);
        }