-
Notifications
You must be signed in to change notification settings - Fork 60
Protect Service with Spring Security and OAuth2
For protecting your services with Spring Security and OAuth2, you need to do several things
dependencies {
// Spring Security and OAuth2
compile group: 'org.springframework.cloud', name: 'spring-cloud-security'
compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.1.3.RELEASE'
// For storing credentials and roles in database
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.0.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-autoconfigure', version: '1.5.0.RELEASE'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.38'
}
After Spring Boot 1.5, the order of the OAuth2 resource filter has been changed. So you need to restore it to the original default value. Otherwise when you hit the URL: http://localhost:8901/auth/user
to retrieve the user information, it will return a login page rather than the user information in JSON.
security:
oauth2:
resource:
filter-order: 3
For storing client application's credential, it can be stored in
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // Define what client applications are registered with the service
clients.inMemory() // Store the application information in memory
.withClient("eagleeye") // Specify which client application will register
.secret("thisissecret") // Specify the secret which will be used to get the access token
.authorizedGrantTypes("refresh_token", "password", "client_credentials") // Provide a list of the authorization grant types that will be supported by the service
.scopes("webclient", "mobileclient"); // Define the types of the client applications can get the access token from the service
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
See Store Clients and Users' Credentials to DB
For storing client users' credentials and roles, it can be stored in
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("john.carnell").password("password1").roles("USER") // Define the first user: john.carnell with the password "password1" and the role "USER"
.and()
.withUser("william.woodward").password("password2").roles("USER", "ADMIN"); // Define the second user: william.woodward with the password "password2" and the role "ADMIN"
}
}
See Store Clients and Users' Credentials to DB
(Need to do)
We will hit the endpoint of the authentication service to get the access token.
-
Method: POST
-
Authentication
- Type: Basic Auth
- Username: eagleeye
- Password: thisissecret
-
Body:
Key Value grant_type password scope webclient username john.carnell password password1
After sending the HTTP request to the authentication service with the credential, it will return the access token:
{
"access_token": "945ab1d3-beec-4e57-839b-bee7ef2cb167",
"token_type": "bearer",
"refresh_token": "fca36d96-debb-430d-a7d1-adcffe512034",
"expires_in": 43199,
"scope": "webclient"
}
The value 945ab1d3-beec-4e57-839b-bee7ef2cb167
is the access token.
In this example, we will use the organization service as a protected service.
dependencies {
// Spring Security and OAuth2
compile group: 'org.springframework.cloud', name: 'spring-cloud-security'
compile group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: '2.1.3.RELEASE'
}
You need to let the protected service know where is the authentication service which can validate the OAuth2 access token.
security:
oauth2:
resource:
userInfoUri: http://localhost:8901/auth/user # This is the URL to validate the access token
@EnableResourceServer // Enable this service as the protected resource by OAuth2
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
You can give permissions to:
ResourceServerConfiguration.java
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception{
http
.authorizeRequests()
.anyRequest()
.authenticated();
}
}
ResourceServerConfiguration.java
@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception{
http
.authorizeRequests()
.antMatchers(HttpMethod.DELETE, "/v1/organizations/**")
.hasRole("ADMIN") // Only ADMIN role have the permission to do DELETE operations
.anyRequest()
.authenticated();
}
}
After setting up the protected service, when you sent a HTTP request to that protected service, the header of the request should contain the access token.
- URL: http://localhost:8060/v1/organizations/e254f8c-c442-4ebe-a82a-e2fc1d1ff78a
- Method: GET
- Headers:
Key | Value |
---|---|
Authorization | Bearer 945ab1d3-beec-4e57-839b-bee7ef2cb167 |
(You may need to get a new access token for your case)
- Overview
- Getting Started
-
Technical Essentials
- Autowired
- SpringData JPA
- Configuration File Auto-loading
- Configuration Encryption
- Service Discovery with Eureka
- Resiliency Patterns with Hystrix
- Configure Hystrix
- Service Gateway with Zuul
- Zuul Filters
- Protect Service with Spring Security and OAuth2
- Use JWT as Access Token
- Store Clients and Users' Credentials to DB
- Integrate with Message Queue (Kafka)
- Integrate with Redis
- Tune Logging
- Log Aggregation
- Send Trace to Zipkin
- Build Runnable Jar
- Core Application Logic
- Components