private void CreateRefreshToken(AuthenticationTokenCreateContext context) { context.SetToken(context.SerializeTicket()); }
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()); } }
private void CreateAuthenticationCode(AuthenticationTokenCreateContext context) { context.SetToken(Guid.NewGuid().ToString("n") + Guid.NewGuid().ToString("n")); _authenticationCodes[context.Token] = context.SerializeTicket(); }
private async Task InvokeTokenEndpointAsync() { DateTimeOffset currentUtc = Options.SystemClock.UtcNow; // remove milliseconds in case they don't round-trip currentUtc = currentUtc.Subtract(TimeSpan.FromMilliseconds(currentUtc.Millisecond)); var form = await Request.ReadFormAsync(); IDictionary <string, StringValues> fields = form.ToDictionary(keyValuePair => keyValuePair.Key, keyValuePair => keyValuePair.Value); var clientContext = new OAuthValidateClientAuthenticationContext(Context, Options, fields); await Options.Provider.ValidateClientAuthentication(clientContext); if (!clientContext.IsValidated) { Logger.LogError("clientID is not valid."); if (!clientContext.HasError) { clientContext.SetError(Constants.Errors.InvalidClient); } await SendErrorAsJsonAsync(clientContext); return; } var tokenEndpointRequest = new TokenEndpointRequest(fields); var validatingContext = new OAuthValidateTokenRequestContext(Context, Options, tokenEndpointRequest, clientContext); AuthenticationTicket ticket = null; if (tokenEndpointRequest.IsAuthorizationCodeGrantType) { // Authorization Code Grant http://tools.ietf.org/html/rfc6749#section-4.1 // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.1.3 ticket = await InvokeTokenEndpointAuthorizationCodeGrantAsync(validatingContext, currentUtc); } else if (tokenEndpointRequest.IsResourceOwnerPasswordCredentialsGrantType) { // Resource Owner Password Credentials Grant http://tools.ietf.org/html/rfc6749#section-4.3 // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.3.2 ticket = await InvokeTokenEndpointResourceOwnerPasswordCredentialsGrantAsync(validatingContext, currentUtc); } else if (tokenEndpointRequest.IsClientCredentialsGrantType) { // Client Credentials Grant http://tools.ietf.org/html/rfc6749#section-4.4 // Access Token Request http://tools.ietf.org/html/rfc6749#section-4.4.2 ticket = await InvokeTokenEndpointClientCredentialsGrantAsync(validatingContext, currentUtc); } else if (tokenEndpointRequest.IsRefreshTokenGrantType) { // Refreshing an Access Token // http://tools.ietf.org/html/rfc6749#section-6 ticket = await InvokeTokenEndpointRefreshTokenGrantAsync(validatingContext, currentUtc); } else if (tokenEndpointRequest.IsCustomExtensionGrantType) { // Defining New Authorization Grant Types // http://tools.ietf.org/html/rfc6749#section-8.3 ticket = await InvokeTokenEndpointCustomGrantAsync(validatingContext, currentUtc); } else { // Error Response http://tools.ietf.org/html/rfc6749#section-5.2 // The authorization grant type is not supported by the // authorization server. Logger.LogError("grant type is not recognized"); validatingContext.SetError(Constants.Errors.UnsupportedGrantType); } if (ticket == null) { await SendErrorAsJsonAsync(validatingContext); return; } ticket.Properties.IssuedUtc = currentUtc; ticket.Properties.ExpiresUtc = currentUtc.Add(Options.AccessTokenExpireTimeSpan); var tokenEndpointContext = new OAuthTokenEndpointContext(Context, Options, ticket, tokenEndpointRequest); await Options.Provider.TokenEndpoint(tokenEndpointContext); if (tokenEndpointContext.TokenIssued) { ticket = new AuthenticationTicket(tokenEndpointContext.Principal, tokenEndpointContext.Properties, tokenEndpointContext.Options.AuthenticationScheme); } else { Logger.LogError("Token was not issued to tokenEndpointContext"); validatingContext.SetError(Constants.Errors.InvalidGrant); await SendErrorAsJsonAsync(validatingContext); return; } var accessTokenContext = new AuthenticationTokenCreateContext( Context, Options.AccessTokenFormat, ticket); await Options.AccessTokenProvider.CreateAsync(accessTokenContext); string accessToken = accessTokenContext.Token; if (string.IsNullOrEmpty(accessToken)) { accessToken = accessTokenContext.SerializeTicket(); } DateTimeOffset?accessTokenExpiresUtc = ticket.Properties.ExpiresUtc; var refreshTokenCreateContext = new AuthenticationTokenCreateContext(Context, Options.RefreshTokenFormat, accessTokenContext.Ticket); await Options.RefreshTokenProvider.CreateAsync(refreshTokenCreateContext); string refreshToken = refreshTokenCreateContext.Token; var tokenEndpointResponseContext = new OAuthTokenEndpointResponseContext(Context, Options, ticket, tokenEndpointRequest, accessToken, tokenEndpointContext.AdditionalResponseParameters); await Options.Provider.TokenEndpointResponse(tokenEndpointResponseContext); MemoryStream stream, memoryStream = null; string body; try { stream = memoryStream = new MemoryStream(); using (var writer = new JsonTextWriter(new StreamWriter(memoryStream))) { memoryStream = null; writer.WriteStartObject(); writer.WritePropertyName(Constants.Parameters.AccessToken); writer.WriteValue(accessToken); writer.WritePropertyName(Constants.Parameters.TokenType); writer.WriteValue(Constants.TokenTypes.Bearer); if (accessTokenExpiresUtc.HasValue) { TimeSpan?expiresTimeSpan = accessTokenExpiresUtc - currentUtc; var expiresIn = (long)expiresTimeSpan.Value.TotalSeconds; if (expiresIn > 0) { writer.WritePropertyName(Constants.Parameters.ExpiresIn); writer.WriteValue(expiresIn); } } if (!string.IsNullOrEmpty(refreshToken)) { writer.WritePropertyName(Constants.Parameters.RefreshToken); writer.WriteValue(refreshToken); } foreach (var additionalResponseParameter in tokenEndpointResponseContext.AdditionalResponseParameters) { writer.WritePropertyName(additionalResponseParameter.Key); writer.WriteValue(additionalResponseParameter.Value); } writer.WriteEndObject(); writer.Flush(); body = Encoding.UTF8.GetString(stream.ToArray()); Response.ContentType = "application/json;charset=UTF-8"; Response.Headers["Cache-Control"] = "no-cache"; Response.Headers["Pragma"] = "no-cache"; Response.Headers["Expires"] = "-1"; Response.ContentLength = Encoding.UTF8.GetByteCount(body); } } finally { if (memoryStream != null) { memoryStream.Dispose(); } } await Response.WriteAsync(body, Encoding.UTF8, Context.RequestAborted); }