使用 OAuth2 实现 Spring RESTful Web 服务 - 将 id 令牌保存为 id 会话
Posted
技术标签:
【中文标题】使用 OAuth2 实现 Spring RESTful Web 服务 - 将 id 令牌保存为 id 会话【英文标题】:Implement Spring RESTful Web Services with OAuth2 - Save id token as id session 【发布时间】:2018-10-29 03:27:27 【问题描述】:我已经在带有 id 令牌的 Spring Boot 中使用 OAuth2 实现了 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_token 并不相同,因为 id_token 仅保存在内存中,并且当用户调用身份验证时,可能会从服务器 1 获取 id_token1 以及调用请求时负载均衡器路由到服务器 2,此处不存在 id_token1。解决此问题的一个选项是使用 Redis(例如)来保存 id_token,另一个选项也可以使用 JWT。由于我使用 WebSphere 作为服务器应用程序我想使用会话 id 来在所有服务器上保留 id_token,我认为这不是一个好主意,但我仍然想实现这个解决方案,有您有任何想法如何实施此解决方案?
【问题讨论】:
【参考方案1】:您已经知道两种选择。如果您的想法是使应用程序无状态,我建议您使用 JWT。但是,它的代价是为 JWT 添加额外的安全性,这样您就不会暴露您的令牌,因为一切都将在客户端。使用 JWT 的一个主要优势是您不必担心需要提供给 redis 服务器的额外服务器/资源。
【讨论】:
我需要使用 session_id 而不是我说的两个选项。 您能解释一下您为什么要这样做吗?如果你真的必须这样做,你可以集群你的服务器并使用粘性会话。 由于Enterprise的内部政治,他们不想改变id token 而不是JWT,所以我需要使用session id。以上是关于使用 OAuth2 实现 Spring RESTful Web 服务 - 将 id 令牌保存为 id 会话的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spring Cloud Security 实现 OAuth2“令牌交换”
使用 Spring Security 实现 OAuth2 隐式授权
使用 Spring Boot 1.5 在 oauth2 实现中返回错误凭据