// Logout, delete refresh-token. public override async Task HandleLogoutRequest(HandleLogoutRequestContext context) { if (context.Request.IsRefreshTokenGrantType()) { if (!await DatabaseProvider.IsRefreshTokenExists(context.Request.RefreshToken)) { // Handle response ourselves and return an object context.HandleResponse(); context.HttpContext.Response.ContentType = "application/json"; context.HttpContext.Response.StatusCode = 400; await context.HttpContext.Response.WriteAsync( JsonConvert.SerializeObject( new { error = OpenIdConnectConstants.Errors.InvalidToken, error_description = "Invalid token." })); return; } await DatabaseProvider.DeleteRefreshToken(context.Request.RefreshToken); context.HandleResponse(); } }
public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) { var options = (OpenIddictServerOptions)context.Options; // If no request_id parameter can be found in the current request, assume the OpenID Connect // request was not serialized yet and store the entire payload in the distributed cache // to make it easier to flow across requests and internal/external logout workflows. if (options.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { // Generate a 256-bit request identifier using a crypto-secure random number generator. var bytes = new byte[256 / 8]; options.RandomNumberGenerator.GetBytes(bytes); context.Request.RequestId = Base64UrlEncoder.Encode(bytes); // Store the serialized logout request parameters in the distributed cache. var stream = new MemoryStream(); using (var writer = new BsonDataWriter(stream)) { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); serializer.Serialize(writer, context.Request); } // Note: the cache key is always prefixed with a specific marker // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; await options.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions { AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); // Create a new logout request containing only the request_id parameter. var address = QueryHelpers.AddQueryString( uri: context.HttpContext.Request.Scheme + "://" + context.HttpContext.Request.Host + context.HttpContext.Request.PathBase + context.HttpContext.Request.Path, name: OpenIdConnectConstants.Parameters.RequestId, value: context.Request.RequestId); context.HttpContext.Response.Redirect(address); // Mark the response as handled // to skip the rest of the pipeline. context.HandleResponse(); return; } await _eventService.PublishAsync(new OpenIddictServerEvents.HandleLogoutRequest(context)); }
public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) { var services = context.HttpContext.RequestServices.GetRequiredService <OpenIddictServices <TApplication, TAuthorization, TScope, TToken> >(); // If no request_id parameter can be found in the current request, assume the OpenID Connect // request was not serialized yet and store the entire payload in the distributed cache // to make it easier to flow across requests and internal/external logout workflows. if (string.IsNullOrEmpty(context.Request.RequestId)) { // Generate a request identifier. Note: using a crypto-secure // random number generator is not necessary in this case. context.Request.RequestId = Guid.NewGuid().ToString(); // Store the serialized logout request parameters in the distributed cache. var stream = new MemoryStream(); using (var writer = new BsonWriter(stream)) { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); serializer.Serialize(writer, context.Request); } // Note: the cache key is always prefixed with a specific marker // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; await services.Options.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions { AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); // Create a new logout request containing only the request_id parameter. var address = QueryHelpers.AddQueryString( uri: context.HttpContext.Request.Scheme + "://" + context.HttpContext.Request.Host + context.HttpContext.Request.PathBase + context.HttpContext.Request.Path, name: OpenIdConnectConstants.Parameters.RequestId, value: context.Request.RequestId); context.HttpContext.Response.Redirect(address); // Mark the response as handled // to skip the rest of the pipeline. context.HandleResponse(); return; } }
public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) { //var services = context.HttpContext.RequestServices.GetRequiredService<OpenIddictServices<TUser, TApplication>>(); var signinManager = context.HttpContext.RequestServices.GetService <SignInManager <ApplicationUser> >(); // Only validate the id_token_hint if the user is still logged in. // If the authentication cookie doesn't exist or is no longer valid, // the user agent is immediately redirected to the client application. if (context.HttpContext.User.Identities.Any(identity => identity.IsAuthenticated)) { // Ensure that the authentication cookie contains the required NameIdentifier claim. // If it cannot be found, ignore the logout request and continue to the next middleware. var identifier = context.HttpContext.User.GetClaim(ClaimTypes.NameIdentifier); if (string.IsNullOrEmpty(identifier)) { return; } // When the client application sends an id_token_hint parameter, the corresponding identity can be retrieved using // AuthenticateAsync and used as a way to determine whether the logout request has been sent by a legit caller. // If the token cannot be extracted, don't handle the logout request at this stage and continue to the next middleware. var principal = await context.HttpContext.Authentication.AuthenticateAsync(context.Options.AuthenticationScheme); if (principal == null) { return; } // Ensure that the identity token corresponds to the authenticated user. If the token cannot be // validated, don't handle the logout request at this stage and continue to the next middleware. if (!principal.HasClaim(ClaimTypes.NameIdentifier, identifier)) { return; } // Delete the ASP.NET Core Identity cookies. await signinManager.SignOutAsync(); } // Redirect the user agent back to the client application. await context.HttpContext.Authentication.SignOutAsync(context.Options.AuthenticationScheme); // Mark the response as handled // to skip the rest of the pipeline. context.HandleResponse(); }