public async Task <ActionResult> ProcessRedirection( AuthorizationParameter authorizationParameter, string code, string subject, List <Claim> claims, string issuerName) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } var client = await _clientRepository.GetClientByIdAsync(authorizationParameter.ClientId); if (client == null) { throw new InvalidOperationException(string.Format(ErrorDescriptions.TheClientIdDoesntExist, authorizationParameter.ClientId)); } // Redirect to the consent page if the prompt parameter contains "consent" ActionResult result; var prompts = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt); if (prompts != null && prompts.Contains(PromptParameter.consent)) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.ConsentIndex; result.RedirectInstruction.AddParameter("code", code); return(result); } var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter); // If there's already one consent then redirect to the callback if (assignedConsent != null) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirectionToCallBackUrl(); var claimsIdentity = new ClaimsIdentity(claims, "simpleIdentityServer"); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); await _generateAuthorizationResponse.ExecuteAsync(result, authorizationParameter, claimsPrincipal, client, issuerName); var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseMode.None) { var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var authorizationFlow = GetAuthorizationFlow(responseTypes, authorizationParameter.State); responseMode = GetResponseMode(authorizationFlow); } result.RedirectInstruction.ResponseMode = responseMode; return(result); } // If there's no consent & there's no consent prompt then redirect to the consent screen. result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.ConsentIndex; result.RedirectInstruction.AddParameter("code", code); return(result); }
public async Task <ActionResult> GetAuthorization(AuthorizationParameter parameter, IPrincipal claimsPrincipal) { var processId = Guid.NewGuid().ToString(); _eventPublisher.Publish(new AuthorizationRequestReceived(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(parameter), 0)); try { var client = await _authorizationCodeGrantTypeParameterValidator.ValidateAsync(parameter); ActionResult actionResult = null; _simpleIdentityServerEventSource.StartAuthorization(parameter.ClientId, parameter.ResponseType, parameter.Scope, parameter.Claims == null ? string.Empty : parameter.Claims.ToString()); if (client.RequirePkce && (string.IsNullOrWhiteSpace(parameter.CodeChallenge) || parameter.CodeChallengeMethod == null)) { throw new IdentityServerException(ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.TheClientRequiresPkce, parameter.ClientId)); } var responseTypes = _parameterParserHelper.ParseResponseTypes(parameter.ResponseType); var authorizationFlow = _authorizationFlowHelper.GetAuthorizationFlow(responseTypes, parameter.State); switch (authorizationFlow) { case AuthorizationFlow.AuthorizationCodeFlow: actionResult = await _getAuthorizationCodeOperation.Execute(parameter, claimsPrincipal, client); break; case AuthorizationFlow.ImplicitFlow: actionResult = await _getTokenViaImplicitWorkflowOperation.Execute(parameter, claimsPrincipal, client); break; case AuthorizationFlow.HybridFlow: actionResult = await _getAuthorizationCodeAndTokenViaHybridWorkflowOperation.Execute(parameter, claimsPrincipal, client); break; } if (actionResult != null) { var actionTypeName = Enum.GetName(typeof(TypeActionResult), actionResult.Type); var actionName = string.Empty; if (actionResult.Type == TypeActionResult.RedirectToAction) { var actionEnum = actionResult.RedirectInstruction.Action; actionName = Enum.GetName(typeof(IdentityServerEndPoints), actionEnum); } var serializedParameters = actionResult.RedirectInstruction == null || actionResult.RedirectInstruction.Parameters == null ? String.Empty : actionResult.RedirectInstruction.Parameters.SerializeWithJavascript(); _simpleIdentityServerEventSource.EndAuthorization(actionTypeName, actionName, serializedParameters); } _eventPublisher.Publish(new AuthorizationGranted(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(actionResult), 1)); actionResult.ProcessId = processId; return(actionResult); } catch (IdentityServerException ex) { _eventPublisher.Publish(new OpenIdErrorReceived(Guid.NewGuid().ToString(), processId, ex.Code, ex.Message, 1)); throw; } }
/// <summary> /// This method is executed when the user confirm the consent /// 1). If there's already consent confirmed in the past by the resource owner /// 1).* then we generate an authorization code and redirects to the callback. /// 2). If there's no consent then we insert it and the authorization code is returned /// 2°.* to the callback url. /// </summary> /// <param name="authorizationParameter">Authorization code grant-type</param> /// <param name="claimsPrincipal">Resource owner's claims</param> /// <returns>Redirects the authorization code to the callback.</returns> public async Task <ActionResult> Execute( AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } if (claimsPrincipal == null || claimsPrincipal.Identity == null) { throw new ArgumentNullException(nameof(claimsPrincipal)); } var client = await _clientRepository.GetClientByIdAsync(authorizationParameter.ClientId); if (client == null) { throw new InvalidOperationException(string.Format("the client id {0} doesn't exist", authorizationParameter.ClientId)); } var subject = claimsPrincipal.GetSubject(); Common.Models.Consent assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter); // Insert a new consent. if (assignedConsent == null) { var claimsParameter = authorizationParameter.Claims; if (claimsParameter.IsAnyIdentityTokenClaimParameter() || claimsParameter.IsAnyUserInfoClaimParameter()) { // A consent can be given to a set of claims assignedConsent = new Common.Models.Consent { Client = client, ResourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject), Claims = claimsParameter.GetClaimNames() }; } else { // A consent can be given to a set of scopes assignedConsent = new Common.Models.Consent { Client = client, GrantedScopes = (await GetScopes(authorizationParameter.Scope)).ToList(), ResourceOwner = await _authenticateResourceOwnerService.AuthenticateResourceOwnerAsync(subject), }; } // A consent can be given to a set of claims await _consentRepository.InsertAsync(assignedConsent); _simpleIdentityServerEventSource.GiveConsent(subject, authorizationParameter.ClientId, assignedConsent.Id); } var result = _actionResultFactory.CreateAnEmptyActionResultWithRedirectionToCallBackUrl(); await _generateAuthorizationResponse.ExecuteAsync(result, authorizationParameter, claimsPrincipal, client); // If redirect to the callback and the responde mode has not been set. if (result.Type == TypeActionResult.RedirectToCallBackUrl) { var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseMode.None) { var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var authorizationFlow = GetAuthorizationFlow(responseTypes, authorizationParameter.State); responseMode = GetResponseMode(authorizationFlow); } result.RedirectInstruction.ResponseMode = responseMode; } return(result); }
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); }
/// <returns>Action result.</returns> public async Task <DisplayContentResult> Execute(AuthorizationParameter authorizationParameter, string authenticatedSubject, string issuerName) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } if (string.IsNullOrWhiteSpace(authenticatedSubject)) { throw new ArgumentNullException(nameof(authenticatedSubject)); } var client = await _clientRepository.GetClientByIdAsync(authorizationParameter.ClientId); if (client == null) { throw new IdentityServerExceptionWithState(ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.ClientIsNotValid, authorizationParameter.ClientId), authorizationParameter.State); } ActionResult actionResult; var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(authenticatedSubject, authorizationParameter).ConfigureAwait(false); // If there's already a consent then redirect to the callback if (assignedConsent != null) { actionResult = _actionResultFactory.CreateAnEmptyActionResultWithRedirectionToCallBackUrl(); await _generateAuthorizationResponse.ExecuteAsync(actionResult, authorizationParameter, client, issuerName, authenticatedSubject).ConfigureAwait(false); var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseMode.None) { var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var authorizationFlow = GetAuthorizationFlow(responseTypes, authorizationParameter.State); responseMode = GetResponseMode(authorizationFlow); } actionResult.RedirectInstruction.ResponseMode = responseMode; return(new DisplayContentResult { ActionResult = actionResult }); } ICollection <string> allowedClaims = null; ICollection <Scope> allowedScopes = null; var claimsParameter = authorizationParameter.Claims; if (claimsParameter.IsAnyIdentityTokenClaimParameter() || claimsParameter.IsAnyUserInfoClaimParameter()) { allowedClaims = claimsParameter.GetClaimNames(); } else { allowedScopes = (await GetScopes(authorizationParameter.Scope)) .Where(s => s.IsDisplayedInConsent) .ToList(); } actionResult = _actionResultFactory.CreateAnEmptyActionResultWithOutput(); return(new DisplayContentResult { AllowedClaims = allowedClaims, Scopes = allowedScopes, ActionResult = actionResult, Client = client }); }
public async Task ExecuteAsync(ActionResult actionResult, AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Client client) { if (actionResult == null || actionResult.RedirectInstruction == null) { throw new ArgumentNullException(nameof(actionResult)); } ; if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } if (claimsPrincipal == null) { throw new ArgumentNullException(nameof(claimsPrincipal)); } if (client == null) { throw new ArgumentNullException(nameof(client)); } var newAccessTokenGranted = false; var allowedTokenScopes = string.Empty; GrantedToken grantedToken = null; var newAuthorizationCodeGranted = false; AuthorizationCode authorizationCode = null; _simpleIdentityServerEventSource.StartGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId, authorizationParameter.ResponseType); var responses = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var idTokenPayload = await GenerateIdTokenPayload(claimsPrincipal, authorizationParameter); var userInformationPayload = await GenerateUserInformationPayload(claimsPrincipal, authorizationParameter); if (responses.Contains(ResponseType.token)) // 1. Generate an access token. { if (!string.IsNullOrWhiteSpace(authorizationParameter.Scope)) { allowedTokenScopes = string.Join(" ", _parameterParserHelper.ParseScopes(authorizationParameter.Scope)); } grantedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId, userInformationPayload, idTokenPayload); if (grantedToken == null) { grantedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes, userInformationPayload, idTokenPayload); newAccessTokenGranted = true; } actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.AccessTokenName, grantedToken.AccessToken); } if (responses.Contains(ResponseType.code)) // 2. Generate an authorization code. { var subject = claimsPrincipal == null ? string.Empty : claimsPrincipal.GetSubject(); var assignedConsent = await _consentHelper.GetConfirmedConsentsAsync(subject, authorizationParameter); if (assignedConsent != null) { // Insert a temporary authorization code // It will be used later to retrieve tha id_token or an access token. authorizationCode = new AuthorizationCode { Code = Guid.NewGuid().ToString(), RedirectUri = authorizationParameter.RedirectUrl, CreateDateTime = DateTime.UtcNow, ClientId = authorizationParameter.ClientId, Scopes = authorizationParameter.Scope, IdTokenPayload = idTokenPayload, UserInfoPayLoad = userInformationPayload }; newAuthorizationCodeGranted = true; actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.AuthorizationCodeName, authorizationCode.Code); } } _jwtGenerator.FillInOtherClaimsIdentityTokenPayload(idTokenPayload, authorizationCode == null ? string.Empty : authorizationCode.Code, grantedToken == null ? string.Empty : grantedToken.AccessToken, authorizationParameter, client); if (newAccessTokenGranted) // 3. Insert the stateful access token into the DB OR insert the access token into the caching. { await _tokenStore.AddToken(grantedToken); _simpleIdentityServerEventSource.GrantAccessToClient(authorizationParameter.ClientId, grantedToken.AccessToken, allowedTokenScopes); } if (newAuthorizationCodeGranted) // 4. Insert the authorization code into the caching. { if (client.RequirePkce) { authorizationCode.CodeChallenge = authorizationParameter.CodeChallenge; authorizationCode.CodeChallengeMethod = authorizationParameter.CodeChallengeMethod; } await _authorizationCodeStore.AddAuthorizationCode(authorizationCode); _simpleIdentityServerEventSource.GrantAuthorizationCodeToClient(authorizationParameter.ClientId, authorizationCode.Code, authorizationParameter.Scope); } if (responses.Contains(ResponseType.id_token)) { var idToken = await GenerateIdToken(idTokenPayload, authorizationParameter); actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.IdTokenName, idToken); } if (!string.IsNullOrWhiteSpace(authorizationParameter.State)) { actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.StateName, authorizationParameter.State); } var sessionState = GetSessionState(authorizationParameter.ClientId, authorizationParameter.OriginUrl, authorizationParameter.SessionId); if (sessionState != null) { actionResult.RedirectInstruction.AddParameter(Constants.StandardAuthorizationResponseNames.SessionState, sessionState); } if (authorizationParameter.ResponseMode == ResponseMode.form_post) { actionResult.Type = TypeActionResult.RedirectToAction; actionResult.RedirectInstruction.Action = IdentityServerEndPoints.FormIndex; actionResult.RedirectInstruction.AddParameter("redirect_uri", authorizationParameter.RedirectUrl); } // Set the response mode if (actionResult.Type == TypeActionResult.RedirectToCallBackUrl) { var responseMode = authorizationParameter.ResponseMode; if (responseMode == ResponseMode.None) { var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); var authorizationFlow = _authorizationFlowHelper.GetAuthorizationFlow(responseTypes, authorizationParameter.State); responseMode = GetResponseMode(authorizationFlow); } actionResult.RedirectInstruction.ResponseMode = responseMode; } _simpleIdentityServerEventSource.EndGeneratingAuthorizationResponseToClient(authorizationParameter.ClientId, actionResult.RedirectInstruction.Parameters.SerializeWithJavascript()); }