I already have a OAuth2 authorization server running in another project. Now I would need to secure several simple spring-boot rest-servers with OAuth2. But I'm finding the Spring documentation really really limited when it comes to separating Authorization and Resource servers.
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". 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.
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)?
There's this thing called RemoteTokenServices that seems promising but it's not really documented at all.
That's obviously one of Spring Security best practices. For Spring Boot microservices we can use a component called Spring Cloud Config Server. Since it is built on top of Spring MVC we may easily enable a secure connection on the server-side. On the client-side, we use a component called Spring Cloud Config Client.
OAuth API Authentication OAuth 2.0 provides an industry-standard protocol for authorizing users in distributed systems. In the context of microservices, the OAuth 2.0 client credential flow supports secure server-to-server communication between API clients and API servers.
Spring Security handles the Authentication and Spring Security OAuth2 handles the Authorization. To configure and enable the OAuth 2.0 Authorization Server we have to use @EnableAuthorizationServer annotation. Some important points.
While configuring your auh server::
Create a new clientDetails in ClientDetailsServiceConfigurer
for resource server. which will be used to configure RemoteTokenService
.
Configure Spring Security OAuth2 in your resource server:
Create a class which is annotate with @EnableWebSecurity
,@Configuration
and extends 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
.
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.)
@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.
@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
.
@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.
HttpSecurity : This will configure security filter to tell it that user requires authentication for protected URLs (APIs).
@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.
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
will not create session.
PS:: If any thing is wrong then tell me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With