private async Task <bool> InvokeAuthorizeEndpointAsync() { var authorizeRequest = new AuthorizeEndpointRequest(Request.Query); var clientContext = new OAuthValidateClientRedirectUriContext( Context, Options, authorizeRequest.ClientId, authorizeRequest.RedirectUri); if (!String.IsNullOrEmpty(authorizeRequest.RedirectUri)) { bool acceptableUri = true; Uri validatingUri; if (!Uri.TryCreate(authorizeRequest.RedirectUri, UriKind.Absolute, out validatingUri)) { // The redirection endpoint URI MUST be an absolute URI // http://tools.ietf.org/html/rfc6749#section-3.1.2 acceptableUri = false; } else if (!String.IsNullOrEmpty(validatingUri.Fragment)) { // The endpoint URI MUST NOT include a fragment component. // http://tools.ietf.org/html/rfc6749#section-3.1.2 acceptableUri = false; } else if (!Options.AllowInsecureHttp && String.Equals(validatingUri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase)) { // The redirection endpoint SHOULD require the use of TLS // http://tools.ietf.org/html/rfc6749#section-3.1.2.1 acceptableUri = false; } if (!acceptableUri) { clientContext.SetError(Constants.Errors.InvalidRequest); return(await SendErrorRedirectAsync(clientContext, clientContext)); } } await Options.Provider.ValidateClientRedirectUriAsync(clientContext); if (!clientContext.IsValidated) { _logger.WriteVerbose("Unable to validate client information"); return(await SendErrorRedirectAsync(clientContext, clientContext)); } var validatingContext = new OAuthValidateAuthorizeRequestContext( Context, Options, authorizeRequest, clientContext); if (string.IsNullOrEmpty(authorizeRequest.ResponseType)) { _logger.WriteVerbose("Authorize endpoint request missing required response_type parameter"); validatingContext.SetError(Constants.Errors.InvalidRequest); } else if (!authorizeRequest.IsAuthorizationCodeGrantType && !authorizeRequest.IsImplicitGrantType) { _logger.WriteVerbose("Authorize endpoint request contains unsupported response_type parameter"); validatingContext.SetError(Constants.Errors.UnsupportedResponseType); } else { await Options.Provider.ValidateAuthorizeRequest(validatingContext); } if (!validatingContext.IsValidated) { // an invalid request is not processed further return(await SendErrorRedirectAsync(clientContext, validatingContext)); } _clientContext = clientContext; _authorizeEndpointRequest = authorizeRequest; var authorizeEndpointContext = new OAuthAuthorizeEndpointContext(Context, Options, authorizeRequest); await Options.Provider.AuthorizeEndpoint(authorizeEndpointContext); return(authorizeEndpointContext.IsRequestCompleted); }
protected override async Task ApplyResponseGrantAsync() { // only successful results of an authorize request are altered if (_clientContext == null || _authorizeEndpointRequest == null || Response.StatusCode != 200) { return; } // only apply with signin of matching authentication type AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType); if (signin == null) { return; } var returnParameter = new Dictionary <string, string>(); if (_authorizeEndpointRequest.IsAuthorizationCodeGrantType) { DateTimeOffset currentUtc = Options.SystemClock.UtcNow; signin.Properties.IssuedUtc = currentUtc; signin.Properties.ExpiresUtc = currentUtc.Add(Options.AuthorizationCodeExpireTimeSpan); // associate client_id with all subsequent tickets signin.Properties.Dictionary[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId; if (!string.IsNullOrEmpty(_authorizeEndpointRequest.RedirectUri)) { // keep original request parameter for later comparison signin.Properties.Dictionary[Constants.Extra.RedirectUri] = _authorizeEndpointRequest.RedirectUri; } var context = new AuthenticationTokenCreateContext( Context, Options.AuthorizationCodeFormat, new AuthenticationTicket(signin.Identity, signin.Properties)); await Options.AuthorizationCodeProvider.CreateAsync(context); string code = context.Token; if (string.IsNullOrEmpty(code)) { _logger.WriteError("response_type code requires an Options.AuthorizationCodeProvider implementing a single-use token."); var errorContext = new OAuthValidateAuthorizeRequestContext(Context, Options, _authorizeEndpointRequest, _clientContext); errorContext.SetError(Constants.Errors.UnsupportedResponseType); await SendErrorRedirectAsync(_clientContext, errorContext); return; } var authResponseContext = new OAuthAuthorizationEndpointResponseContext( Context, Options, new AuthenticationTicket(signin.Identity, signin.Properties), _authorizeEndpointRequest, null, code); await Options.Provider.AuthorizationEndpointResponse(authResponseContext); foreach (var parameter in authResponseContext.AdditionalResponseParameters) { returnParameter[parameter.Key] = parameter.Value.ToString(); } returnParameter[Constants.Parameters.Code] = code; if (!String.IsNullOrEmpty(_authorizeEndpointRequest.State)) { returnParameter[Constants.Parameters.State] = _authorizeEndpointRequest.State; } string location = string.Empty; if (_authorizeEndpointRequest.IsFormPostResponseMode) { location = Options.FormPostEndpoint.ToString(); returnParameter[Constants.Parameters.RedirectUri] = _clientContext.RedirectUri; } else { location = _clientContext.RedirectUri; } foreach (var key in returnParameter.Keys) { location = WebUtilities.AddQueryString(location, key, returnParameter[key]); } Response.Redirect(location); } else if (_authorizeEndpointRequest.IsImplicitGrantType) { string location = _clientContext.RedirectUri; DateTimeOffset currentUtc = Options.SystemClock.UtcNow; signin.Properties.IssuedUtc = currentUtc; signin.Properties.ExpiresUtc = currentUtc.Add(Options.AccessTokenExpireTimeSpan); // associate client_id with access token signin.Properties.Dictionary[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId; var accessTokenContext = new AuthenticationTokenCreateContext( Context, Options.AccessTokenFormat, new AuthenticationTicket(signin.Identity, signin.Properties)); await Options.AccessTokenProvider.CreateAsync(accessTokenContext); string accessToken = accessTokenContext.Token; if (string.IsNullOrEmpty(accessToken)) { accessToken = accessTokenContext.SerializeTicket(); } DateTimeOffset?accessTokenExpiresUtc = accessTokenContext.Ticket.Properties.ExpiresUtc; var appender = new Appender(location, '#'); appender .Append(Constants.Parameters.AccessToken, accessToken) .Append(Constants.Parameters.TokenType, Constants.TokenTypes.Bearer); if (accessTokenExpiresUtc.HasValue) { TimeSpan?expiresTimeSpan = accessTokenExpiresUtc - currentUtc; var expiresIn = (long)(expiresTimeSpan.Value.TotalSeconds + .5); appender.Append(Constants.Parameters.ExpiresIn, expiresIn.ToString(CultureInfo.InvariantCulture)); } if (!String.IsNullOrEmpty(_authorizeEndpointRequest.State)) { appender.Append(Constants.Parameters.State, _authorizeEndpointRequest.State); } var authResponseContext = new OAuthAuthorizationEndpointResponseContext( Context, Options, new AuthenticationTicket(signin.Identity, signin.Properties), _authorizeEndpointRequest, accessToken, null); await Options.Provider.AuthorizationEndpointResponse(authResponseContext); foreach (var parameter in authResponseContext.AdditionalResponseParameters) { appender.Append(parameter.Key, parameter.Value.ToString()); } Response.Redirect(appender.ToString()); } }