Java 使用OAuth2实现Spring RESTful Web服务-将id令牌另存为id会话

Java 使用OAuth2实现Spring RESTful Web服务-将id令牌另存为id会话,java,rest,spring-boot,spring-security,oauth-2.0,Java,Rest,Spring Boot,Spring Security,Oauth 2.0,我已经在Spring Boot中使用OAuth2和id令牌实现了Spring RESTful Web服务: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration;

我已经在Spring Boot中使用OAuth2和id令牌实现了Spring RESTful Web服务:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
    import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
    import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
    import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
    import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;


@Configuration
public class ResourceServerConfig {

    private static final String SERVER_RESOURCE_ID = "oauth2-server";
    private static final Logger LOG = LoggerFactory.getLogger(ResourceServerConfig.class);
    private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Configuration
    @EnableResourceServer
    @Order(2)
    protected class ResourceServer extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
            LOG.info("ResourceServerSecurityConfigurer");
            resources.tokenStore(tokenStore).resourceId(SERVER_RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            LOG.info("HttpSecurity");
            http.anonymous().disable().
                requestMatchers().antMatchers("/v1/**").
                and().authorizeRequests().antMatchers("/v1/**").authenticated();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    @Order(1)
    protected class AuthConfig extends AuthorizationServerConfigurerAdapter {

        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            LOG.info("AuthorizationServerEndpointsConfigurer");
            endpoints.userDetailsService(userDetailsService)
            .authenticationManager(authenticationManager).tokenStore(tokenStore).approvalStoreDisabled();
        }

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            LOG.info("ClientDetailsServiceConfigurer: {}", clients);
            clients.inMemory().withClient("client").authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit", "client_credentials")
                    .authorities("ROLE_CLIENT").scopes("read").resourceIds(SERVER_RESOURCE_ID).secret("secret");
        }


    }
}
我正在使用负载平衡器路由身份验证和调用请求,但所有服务器之间的id_令牌并不相同,因为id_令牌只保存在内存中,当用户调用身份验证时,从服务器1有一个id_令牌1,当调用请求时,可能是到服务器2的负载平衡器路由,这里不存在id_令牌1。解决这个问题的一种方法是使用Redis(例如)保存id_令牌,另一种方法是使用JWT。由于我正在使用WebSphere As server application我想使用会话id在所有服务器上保留id_令牌,我认为这不是一个好主意,但我仍然希望实现此解决方案,您对如何实现此解决方案有何想法


您已经知道了两种选择。如果您的想法是使应用程序无状态,我建议使用JWT。然而,它的代价是为JWT增加额外的安全性,这样您就不会暴露您的令牌,因为所有内容都将在客户端。使用JWT的一个主要优点是,您不必担心需要向redis server提供的额外服务器/资源。

我需要使用会话id,而不是我说的两个选项。您能解释一下为什么要这样做吗?你可以集群你的服务器,如果你真的需要的话,可以使用sticky session。由于企业内部的政治原因,他们不想更改id令牌而不是JWT,所以我需要使用session id。