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); }