How to persist OAuth2AuthorizedClient in redis-session

二次信任 提交于 2020-05-31 04:05:41

问题


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.

application.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://....
    ...

Controller.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";

        }

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

EDIT:

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


回答1:


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();
    }

controller.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();
    }


来源:https://stackoverflow.com/questions/61893795/how-to-persist-oauth2authorizedclient-in-redis-session

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!