// Validate the grant_type and the client application credentials public override async Task ValidateTokenRequest(ValidateTokenRequestContext context) { // Reject the token requests that don't use grant_type=password or grant_type=refresh_token. if (!context.Request.IsPasswordGrantType() && !context.Request.IsRefreshTokenGrantType()) { context.Reject( error: OpenIdConnectConstants.Errors.UnsupportedGrantType, description: "Only grant_type=password or grant_type=refresh_token are accepted by this server."); return; } // Check if refresh-token exists in DB if (context.Request.IsRefreshTokenGrantType()) { var id = RefreshTokenProvider.GenerateId(context.Request.RefreshToken); if (!await RavenDatabaseProvider.IsEntityExists(id)) { context.Reject( error: OpenIdConnectConstants.Errors.InvalidClient, description: "Invalid client."); return; } } // Since there's only one application and since it's a public client // (i.e a client that cannot keep its credentials private), call Skip() // to inform the server the request should be accepted without // enforcing client authentication. context.Skip(); return; }
// Save refresh-token public override async Task ApplyTokenResponse(ApplyTokenResponseContext context) { if (context.Response.Error == null && context.Response.RefreshToken != null) { if (context.Request.IsRefreshTokenGrantType()) { var refreshTokenId = RefreshTokenProvider.GenerateId(context.Request.RefreshToken); await RavenDatabaseProvider.DeleteEntity(refreshTokenId); } string remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress?.ToString(); string userAgent = null; if (context.HttpContext.Request.Headers.ContainsKey("User-Agent")) { userAgent = context.HttpContext.Request.Headers["User-Agent"].ToString(); } await RefreshTokenProvider.CreateAsync( context.Ticket.Principal.Identity.Name, context.Response.RefreshToken, remoteIpAddress, userAgent, context.Options.RefreshTokenLifetime); } return; }