如何在 redis-session 中持久化 OAuth2AuthorizedClient [英] How to persist OAuth2AuthorizedClient in redis-session

查看:160
本文介绍了如何在 redis-session 中持久化 OAuth2AuthorizedClient的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的项目使用带有 springboot 会话和 spring security 5.1.10 的 redis 会话.我刚刚迁移了旧的 oauth2 实现.之前,当我重新启动应用程序时,我仍然拥有 access_token 和 refresh_token.使用此实现,用户已登录,但我丢失了 AuthorizedClients,因此 loadAuthorizedClient 函数在重新启动后返回 null.同样在生产中,我们有许多具有相同应用程序的容器.是否有任何 springboot 标准方法来实现这一目标?比如注册一些bean什么的.

My project uses redis session with springboot session and spring security 5.1.10. I just migrated the old oauth2 implementation. Before, when I restarted the app I still had the access_token and refresh_token. With this implementation the user is logged in, but I loose the AuthorizedClients so loadAuthorizedClient function returns null after restarting. Also in production we have many containers with the same app. Is there any springboot stardard way to achieve this? like register some bean or something.

应用程序.yml

    ...

    session:
        store-type: redis
        redis:
            namespace: spring:session:${spring.application.name}
    redis:
        host: ${redissession.host}
        password: ${redissession.password}
        port: ${redissession.port}

    security:
        oauth2:
            client:
                registration:
                    biocryptology:
                        provider: example
                        client-id: client
                        client-secret: xxx
                        client-authentication-method: basic
                        authorization-grant-type: authorization_code
                        redirect-uri-template: "{baseUrl}/login"
                        scope:
                            - openid
                provider:
                    example:
                        issuer-uri: https://....
    ...

控制器.java

        @Autowired
        private OAuth2AuthorizedClientService clientService;

        @GetMapping("/user")
        public String getOidcUserPrincipal() throws InvalidSessionException {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (!(authentication.getPrincipal() instanceof OidcUser)) {
                throw new InvalidSessionException();
            }

            OidcUser principal = ((OidcUser) authentication.getPrincipal());
            LOG.info("oidc: {}", principal.getName());

            OAuth2AuthenticationToken oauth2Token = (OAuth2AuthenticationToken) authentication;
            LOG.info("authentication: {}", oauth2Token);
            OAuth2AuthorizedClient client = clientService
                    .loadAuthorizedClient(oauth2Token.getAuthorizedClientRegistrationId(), authentication.getName());
            LOG.info("client: {}", client);

            return "logged";

        }

目标是跨容器获取 access_token 和 refresh_token,没有 OAuth2AuthorizedClientService 的其他方式可能吗?

The goal is getting the access_token and refresh_token across containers, any other way without OAuth2AuthorizedClientService maybe?

        <!-- Spring -->
        <spring-cloud.version>Greenwich.SR5</spring-cloud.version>

推荐答案

注册一个 bean 成功了,它将它保存在会话中,但是 OAuth2AuthorizedClientService 在每种情况下都会崩溃,需要一个解决方法搜索在会话中直接或使用 OAuth2AuthorizedClientRepository 自动装配:

Registering a bean did the trick, it saves it in session, but then OAuth2AuthorizedClientService breaks down for every case and needs a workaround searching in session directly or using OAuth2AuthorizedClientRepository autowired:

    @Bean
    public OAuth2AuthorizedClientRepository authorizedClientRepository() {
        return new HttpSessionOAuth2AuthorizedClientRepository();
    }

控制器.java

    @Autowired
    private OAuth2AuthorizedClientRepository clientRepository;

    @GetMapping("/user")
    public Map<String, Object> getOidcUserPrincipal(HttpServletRequest request) throws InvalidSessionException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!(authentication.getPrincipal() instanceof OidcUser)) {
            throw new InvalidSessionException();
        }

        OidcUser principal = ((OidcUser) authentication.getPrincipal());

        OAuth2AuthorizedClient client = clientRepository
                .loadAuthorizedClient(oauth2Token.getAuthorizedClientRegistrationId(), authentication, request);
        LOG.info("client: {}", client);
        if (Objects.nonNull(client)) {
            String token = client.getAccessToken().getTokenValue();
            String refreshtoken = client.getRefreshToken().getTokenValue();

            LOG.info("token: {} {}", token, refreshtoken);
        }

        return principal.getClaims();
    }

这篇关于如何在 redis-session 中持久化 OAuth2AuthorizedClient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆