Provides context information when processing an Authorization Response
Inheritance: BaseOAuthEndpointContext
Beispiel #1
0
        protected override async Task HandleSignInAsync(SignInContext context)
        {
            // only successful results of an authorize request are altered
            if (_clientContext == null || _authorizeEndpointRequest == null || Response.StatusCode != 200)
            {
                return;
            }

            if (context?.Principal == null)
            {
                return;
            }

            AuthenticationResponseGrant signin = new AuthenticationResponseGrant(context.Principal, new AuthenticationProperties(context.Properties));

            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.Items[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId;
                if (!string.IsNullOrEmpty(_authorizeEndpointRequest.RedirectUri))
                {
                    // keep original request parameter for later comparison
                    signin.Properties.Items[Constants.Extra.RedirectUri] = _authorizeEndpointRequest.RedirectUri;
                }

                var tokenCreationContext = new AuthenticationTokenCreateContext(Context, Options.AuthorizationCodeFormat, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType));

                await Options.AuthorizationCodeProvider.CreateAsync(tokenCreationContext);

                string code = tokenCreationContext.Token;
                if (string.IsNullOrEmpty(code))
                {
                    Logger.LogError("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.Principal, signin.Properties, signin.Identity.AuthenticationType), _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 = QueryHelpers.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.Items[Constants.Extra.ClientId] = _authorizeEndpointRequest.ClientId;

                var accessTokenContext = new AuthenticationTokenCreateContext(Context, Options.AccessTokenFormat, new AuthenticationTicket(signin.Principal, signin.Properties, signin.Identity.AuthenticationType));

                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.Principal, signin.Properties, signin.Identity.AuthenticationType), _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());
            }
        }
 /// <summary>
 /// Called before the AuthorizationEndpoint redirects its response to the caller. The response could be the
 /// token, when using implicit flow or the AuthorizationEndpoint when using authorization code flow.  
 /// An application may implement this call in order to do any final modification of the claims being used 
 /// to issue access or refresh tokens. This call may also be used in order to add additional 
 /// response parameters to the authorization endpoint's response.
 /// </summary>
 /// <param name="context">The context of the event carries information in and results out.</param>
 /// <returns>Task to enable asynchronous execution</returns>
 public virtual Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context)
 {
     return OnAuthorizationEndpointResponse.Invoke(context);
 }
Beispiel #3
0
 /// <summary>
 /// Called before the AuthorizationEndpoint redirects its response to the caller. The response could be the
 /// token, when using implicit flow or the AuthorizationEndpoint when using authorization code flow.
 /// An application may implement this call in order to do any final modification of the claims being used
 /// to issue access or refresh tokens. This call may also be used in order to add additional
 /// response parameters to the authorization endpoint's response.
 /// </summary>
 /// <param name="context">The context of the event carries information in and results out.</param>
 /// <returns>Task to enable asynchronous execution</returns>
 public virtual Task AuthorizationEndpointResponse(OAuthAuthorizationEndpointResponseContext context)
 {
     return(OnAuthorizationEndpointResponse.Invoke(context));
 }