예제 #1
0
        // 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;
            }
        }
예제 #4
0
        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();
        }