我面临的是我正在编写一个无状态API,而Spring security 5使用 HttpSessionOAuth2AuthorizationRequestRepository 来存储使用会话的授权请求 . 所以,我认为不要使用它并编写基于cookie的实现,如下所示:

public class HttpCookieOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {

    private static final String COOKIE_NAME = "some-name";

    @Override
    public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {

        Assert.notNull(request, "request cannot be null");

        return fetchCookie(request)
                .map(this::toOAuth2AuthorizationRequest)
                .orElse(null);
    }

    @Override
    public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request,
            HttpServletResponse response) {

        Assert.notNull(request, "request cannot be null");
        Assert.notNull(response, "response cannot be null");

        if (authorizationRequest == null) {

            deleteCookie(request, response);
            return;
        }

        Cookie cookie = new Cookie(COOKIE_NAME, fromAuthorizationRequest(authorizationRequest));
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }


    private String fromAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest) {

        return Base64.getUrlEncoder().encodeToString(
                SerializationUtils.serialize(authorizationRequest));
    }

    private void deleteCookie(HttpServletRequest request, HttpServletResponse response) {

        fetchCookie(request).ifPresent(cookie -> {

            cookie.setValue("");
            cookie.setPath("/");
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        });
    }

    @Override
    public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) {

        // Question: How to remove the cookie, because we don't have access to response object here.
        return loadAuthorizationRequest(request);
    }

    private Optional<Cookie> fetchCookie(HttpServletRequest request) {

        Cookie[] cookies = request.getCookies();

        if (cookies != null && cookies.length > 0)
            for (int i = 0; i < cookies.length; i++)
                if (cookies[i].getName().equals(COOKIE_NAME))
                    return Optional.of(cookies[i]);

        return Optional.empty();
    }

    private OAuth2AuthorizationRequest toOAuth2AuthorizationRequest(Cookie cookie) {

        return SerializationUtils.deserialize(
                Base64.getUrlDecoder().decode(cookie.getValue()));
    }
}

以上基本上将数据存储在cookie而不是会话中 . 我有几个问题:

  • 如何准确编码上面的 removeAuthorizationRequest 方法?我希望在那里删除cookie,但我们无法访问 response 对象 .

  • 上述(基于cookie)方法看起来不错吗?例如 . 任何安全问题?

Update :在https://github.com/spring-projects/spring-security/issues/5313创建了一个问题 . 在此之前,我提出了一个解决方法:https://www.naturalprogrammer.com/blog/1681261/spring-security-5-oauth2-login-signup-stateless-restful-web-services