[英]Microservices and Spring Security OAuth2
I already have a OAuth2 authorization server running in another project. 我已经在另一个项目中运行了OAuth2授权服务器。 Now I would need to secure several simple spring-boot rest-servers with OAuth2.
现在我需要使用OAuth2来保护几个简单的spring-boot rest-servers。 But I'm finding the Spring documentation really really limited when it comes to separating Authorization and Resource servers.
但是我发现Spring文档在分离授权和资源服务器时确实非常有限。
I've also found several questions where the answer has been "Well they can be different boxes as long as they share the same tokenStore datasource". 我还发现了几个问题, 答案是“只要它们共享相同的tokenStore数据源,它们就可以是不同的盒子”。 Can this really be true?
这真的可以吗? How could this ever work for microservices?
这怎么可能对微服务有用? It would seem like a really odd thing that every rest service would need to implement it's own OAuth authorization server.
每个休息服务都需要实现它自己的OAuth授权服务器,这似乎是一件非常奇怪的事情。
So how do I setup Oauth2.0 security for spring-boot rest-endpoints that refer to a remote oauth authorization server (possibly not even written with Spring)? 那么如何为引用远程oauth授权服务器的spring-boot rest-endpoints设置Oauth2.0安全性(可能甚至不用Spring编写)?
There's this thing called RemoteTokenServices that seems promising but it's not really documented at all. 这个名为RemoteTokenServices的东西似乎很有希望,但根本没有记录。
While configuring your auh server:: 配置你的auh服务器::
Create a new clientDetails in ClientDetailsServiceConfigurer
for resource server. 在
ClientDetailsServiceConfigurer
为资源服务器创建新的clientDetails。 which will be used to configure RemoteTokenService
. 这将用于配置
RemoteTokenService
。
Configure Spring Security OAuth2 in your resource server: 在资源服务器中配置Spring Security OAuth2:
Create a class which is annotate with @EnableWebSecurity
, @Configuration
and extends WebSecurityConfigurerAdapter
. 创建一个使用
@EnableWebSecurity
, @Configuration
@EnableWebSecurity
@Configuration
注释的类,并扩展WebSecurityConfigurerAdapter
。
@Configuration
@EnableWebSecurity
protected static class ResourceConfiguration extends WebSecurityConfigurerAdapter {
// methods
}
Create a method with @Bean annotated which will return instance of TokenService
, which will be used to create AuthenticationManager
. 使用@Bean注释创建一个方法,该方法将返回
TokenService
实例,该实例将用于创建AuthenticationManager
。
In this method create an instance of RemoteTokenService
and set clientId, client_secret , checkTokenEndpointUrl and DefaultAccessTokenConverterWithClientRoles
(this class is our implementation to get client_authority while authenticating accessToken in OAuth2 server.) 在此方法中创建
RemoteTokenService
的实例并设置clientId,client_secret,checkTokenEndpointUrl和DefaultAccessTokenConverterWithClientRoles
(此类是我们在OAuth2服务器中验证accessToken时获取client_authority的实现。)
@Bean
public ResourceServerTokenServices tokenService() {
RemoteTokenServices tokenServices = new RemoteTokenServices();
tokenServices.setClientId("resource_id");
tokenServices.setClientSecret("resource_secret");
tokenServices.setCheckTokenEndpointUrl("http://<server-url>: <port>/oauth/check_token");
return tokenServices;
}
Override authenticationManagerBean()
method and annotate it with @Bean
and return an instance of OAuth2AuthenticationManager
with TokenService
injected. 覆盖
authenticationManagerBean()
方法并使用@Bean
注释它,并返回注入了OAuth2AuthenticationManager
的TokenService
实例。
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager authenticationManager = new OAuth2AuthenticationManager();
authenticationManager.setTokenServices(tokenService());
return authenticationManager;
}
Create a class annotated with @EnableResourceServer
, @Configuration
and extend ResourceServerConfigurerAdapter
. 创建一个使用
@EnableResourceServer
, @Configuration
@EnableResourceServer
@Configuration
注释的类并扩展ResourceServerConfigurerAdapter
。
@Configuration
@EnableResourceServer
protected static class ResourceServerConfig extends ResourceServerConfigurerAdapter {
// Mehotds
}
Override Configure methods form the super class to configure resource server. 覆盖配置方法构成超类以配置资源服务器。 Different configurer to configure Resource server.
不同的配置器配置资源服务器。
ResourceServerSecurityConfigurer : to configure Resource_id. ResourceServerSecurityConfigurer :配置Resource_id。
HttpSecurity : This will configure security filter to tell it that user requires authentication for protected URLs (APIs). HttpSecurity :这将配置安全过滤器,告诉用户需要对受保护的URL(API)进行身份验证。
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("resource_id");
}
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
.antMatcher("/**").authenticated()
this line will secure every api url of your resource server. .antMatcher("/**").authenticated()
这一行将保护资源服务器的每个api url。 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
will not create session. .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
不会创建会话。
PS:: If any thing is wrong then tell me. PS ::如果有什么不对的话请告诉我。
It's not really true that both have to share the same database, provided the resource server has some way of validating that the access token is genuine (was issued by the authorizations server) and also some way of decoding it (it may need to know what scopes it grants, for example). 如果资源服务器有某种方式来验证访问令牌是真实的(由授权服务器发布)以及解码它的某种方式(它可能需要知道什么,那么两者都必须共享同一个数据库并不是真的。例如,它授予的范围。 The OAuth2 spec doesn't say anything about how this is to be achieved.
OAuth2规范没有说明如何实现这一目标。
If the resource is in the same process as the authorization server, then sharing the data is an easy option. 如果资源与授权服务器处于同一进程中,则共享数据是一个简单的选择。 Otherwise, it needs some way of translating the token.
否则,它需要某种方式来翻译令牌。 If the token is just an opaque string of random bytes, then obviously it has to exchange it for the real information.
如果令牌只是一个随机字节的不透明字符串,那么显然它必须将它交换为真实信息。 This is what
RemoteTokenServices
does. 这就是
RemoteTokenServices
功能。 The authorization server exposes a /check_token
endpoint to allow the tokens to be decoded. 授权服务器公开
/check_token
端点以允许解码令牌。
An alternative is to actually encode the info in the token and have the authorization server digitally sign it. 另一种方法是实际编码令牌中的信息,并让授权服务器对其进行数字签名。 The resource server can then decode and validate the token itself as long as it understand the format.
然后资源服务器可以解码并验证令牌本身,只要它理解格式即可。
I'd recommend you look at the Cloudfoundry UAA which provides an authorization server out of the box which is implemented using signed JWT tokens (it also exposes the /check_token
endpoint). 我建议您查看Cloudfoundry UAA ,它提供了一个开箱即用的授权服务器,它使用签名的JWT令牌实现(它还公开了
/check_token
端点)。 The Tokens overview and the API docs are probably a good starting point. 令牌概述和API文档可能是一个很好的起点。
A working sample of RemoteTokenService
can be found here . 可以在此处找到
RemoteTokenService
的工作示例。
For more details about check_token
api, you can refer org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.java
有关
check_token
api的更多详细信息,请参阅org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint.java
On the resource server end, OAuth2AuthenticationProcessingFilter
validates OAuth2 token by calling OAuth2AuthenticationManager.authenticate()
method which makes the call to RemoteTokenServices.loadAuthentication()
to validate the token from the Auth Server. 在资源服务器端,
OAuth2AuthenticationProcessingFilter
通过调用OAuth2AuthenticationManager.authenticate()
方法验证OAuth2令牌,该方法调用RemoteTokenServices.loadAuthentication()
以验证来自Auth服务器的令牌。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.