Beispiel #1
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);
            }
        }
        public async Task <ActionResult> ProcessAsync(AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Core.Common.Models.Client client, string issuerName)
        {
            if (authorizationParameter == null)
            {
                throw new ArgumentNullException(nameof(authorizationParameter));
            }

            if (client == null)
            {
                throw new ArgumentNullException(nameof(client));
            }

            var     endUserIsAuthenticated = IsAuthenticated(claimsPrincipal);
            Consent confirmedConsent       = null;

            if (endUserIsAuthenticated)
            {
                confirmedConsent = await GetResourceOwnerConsent(claimsPrincipal, authorizationParameter);
            }

            var serializedAuthorizationParameter = authorizationParameter.SerializeWithJavascript();

            _oauthEventSource.StartProcessingAuthorizationRequest(serializedAuthorizationParameter);
            ActionResult result  = null;
            var          prompts = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt);

            if (prompts == null || !prompts.Any())
            {
                prompts = new List <PromptParameter>();
                if (!endUserIsAuthenticated)
                {
                    prompts.Add(PromptParameter.login);
                }
                else
                {
                    if (confirmedConsent == null)
                    {
                        prompts.Add(PromptParameter.consent);
                    }
                    else
                    {
                        prompts.Add(PromptParameter.none);
                    }
                }
            }

            var redirectionUrls = _clientValidator.GetRedirectionUrls(client, authorizationParameter.RedirectUrl);

            if (!redirectionUrls.Any())
            {
                throw new IdentityServerExceptionWithState(
                          ErrorCodes.InvalidRequestCode,
                          string.Format(ErrorDescriptions.RedirectUrlIsNotValid, authorizationParameter.RedirectUrl),
                          authorizationParameter.State);
            }

            var scopeValidationResult = _scopeValidator.Check(authorizationParameter.Scope, client);

            if (!scopeValidationResult.IsValid)
            {
                throw new IdentityServerExceptionWithState(
                          ErrorCodes.InvalidScope,
                          scopeValidationResult.ErrorMessage,
                          authorizationParameter.State);
            }

            if (!scopeValidationResult.Scopes.Contains(Constants.StandardScopes.OpenId.Name))
            {
                throw new IdentityServerExceptionWithState(
                          ErrorCodes.InvalidScope,
                          string.Format(ErrorDescriptions.TheScopesNeedToBeSpecified, Constants.StandardScopes.OpenId.Name),
                          authorizationParameter.State);
            }

            var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType);

            if (!responseTypes.Any())
            {
                throw new IdentityServerExceptionWithState(
                          ErrorCodes.InvalidRequestCode,
                          string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ResponseTypeName),
                          authorizationParameter.State);
            }

            if (!_clientValidator.CheckResponseTypes(client, responseTypes.ToArray()))
            {
                throw new IdentityServerExceptionWithState(
                          ErrorCodes.InvalidRequestCode,
                          string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType,
                                        authorizationParameter.ClientId,
                                        string.Join(",", responseTypes)),
                          authorizationParameter.State);
            }

            // Check if the user connection is still valid.
            if (endUserIsAuthenticated && !authorizationParameter.MaxAge.Equals(default(double)))
            {
                var authenticationDateTimeClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.AuthenticationInstant);
                if (authenticationDateTimeClaim != null)
                {
                    var maxAge                 = authorizationParameter.MaxAge;
                    var currentDateTimeUtc     = DateTimeOffset.UtcNow.ConvertToUnixTimestamp();
                    var authenticationDateTime = long.Parse(authenticationDateTimeClaim.Value);
                    if (maxAge < currentDateTimeUtc - authenticationDateTime)
                    {
                        result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection();
                        result.RedirectInstruction.Action = IdentityServerEndPoints.AuthenticateIndex;
                    }
                }
            }

            if (result == null)
            {
                result = ProcessPromptParameters(
                    prompts,
                    claimsPrincipal,
                    authorizationParameter,
                    confirmedConsent);

                await ProcessIdTokenHint(result,
                                         authorizationParameter,
                                         prompts,
                                         claimsPrincipal,
                                         issuerName);
            }

            var actionTypeName = Enum.GetName(typeof(TypeActionResult), result.Type);
            var actionName     = result.RedirectInstruction == null
                ? string.Empty
                : Enum.GetName(typeof(IdentityServerEndPoints), result.RedirectInstruction.Action);

            _oauthEventSource.EndProcessingAuthorizationRequest(
                serializedAuthorizationParameter,
                actionTypeName,
                actionName);

            return(result);
        }