Category: Spring Security

Setting up Keycloak Server

Keycloak can be downloaded at :-  https://www.keycloak.org/downloads.html

Once it is downloaded, extract the binary distribution and execute the standalone.sh available in the keycloak-9.0.3/bin to run the keycloak server.

References:- https://www.keycloak.org/docs/latest/server_installation/index.html

 

Adding Realm

We need to add a realm first. This can be done by click on Add realm button on top of the server console.

Screen Shot 2020-04-18 at 3.07.35 PM.png

 

Then add the name for the realm. In my case i have added it as “spring-app-demo-realm“.

1.add_realm.png

Now we have successfully added a realm.

 

Adding new users

Now we need to add new users for the newly added realm. For the demonstration purpose i am filling only the mandatory data. I will be creating two user accounts.

  • username: app-user    /   password: test123
  • username: app-admin    /   password: test123

 

Lets create the “app-user” first.

2.add_user.png

Once the user is added, we need to set the password. This can be done as follows.

3.update_password.png

Repeat the above steps again to create the “admin-user” as well.

 

Create Roles

Now we need to create user roles. we will create following two user roles.

  • ROLE_ADMIN
  • ROLE_USER

 

4. add role.png

 

Screen Shot 2020-05-04 at 3.09.23 PM.png

Now we have successfully created the roles.

 

Assign role(s) for the user

Now this is the time to assign the roles for the user accounts. This can be done as follows.

click on Users. ->  select the user account -> Role Mappings

Assigning the user role for the app-admin user

5. assign role for the user.png

Select the available role(s) -> Add Selected

 

Assigning the user role for the app-user

Screen Shot 2020-05-04 at 3.15.21 PM.png

 

Set up client

Now we need to create new client.

6. add client.png

 

Now we need to do more configurations.

7. configure client.png

 

Now we are done with the setup and configuration process.

 

Testing with Postman

8. testing with POSTman.png

 

REST endpoint should in the following format.

http://localhost:8080/auth/realms/<realm-name>/protocol/openid-connect/token

 

 

 

Microservices: How to use Spring Security OAuth2 to Secure Spring REST Api (Resource Server Set up) – Part 3

This is the Part 3 of the series of articles written to share my experience on securing REST Api(s) with Spring Security OAuth2.  The other pars of this article series have been listed below.

Part 1 :  Basics of OAuth2, Roles, Grant types and Microservices security.

Part 2 :  Setting up Authorization server with Spring Security OAuth2 using In-memory token store and client details

Part 3 :  Setting up Resource Server with Spring Security OAuth2.

Part 4 :  Enhancing Authorization server to store client app details and tokens in the database (JDBC client and token store)

Part 5 :  Secure REST Api with Spring Security OAuth2 using JWT token

Part 6 :  Token Revoke and Invalidating

 

Here we will be focusing on how to configure and set up resource server to expose protected resources and allow their access through a valid access token.

In the part 2 of the article, we have looked at how to set up Authorization server and generate token based on valid credentials. In this article, we are going to use the generated access token to access protected resources available.

 

Generating a Project

You need to generate a spring boot project with following dependencies.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

 

 

REST Api Resources

In WelcomeController, you can see set of endpoints and those are accessible for different user levels (roles). in order to access each endpoint, we need to have a valid token generated against authorized user credentials.


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.security.RolesAllowed;
@RestController
public class WelcomeController {
@GetMapping("/public")
public String welcomePublic() {
return "welcome public/guest user";
}
@RolesAllowed({"ROLE_ADMIN"})
@GetMapping("/admin")
public String welcomeAdmin() {
return "welcome admin";
}
@RolesAllowed({"ROLE_USER"})
@GetMapping("/user")
public String welcomeUser() {
return "welcome user";
}
}

 

/public endpoint can be accessed by any user (both authenticated and non-authenticated). All other endpoints can be accessed only by authenticated users with allowed user roles.  we can declare that behavior as follows.


import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public").permitAll()
.anyRequest().authenticated();
}
}

according to the above configuration, only the access for the /public will be allowed for the non-authenticated users. all other requests should be authenticated requests.

 

Verifying and Validating the Tokens

You might be thinking of how the resource server internally verify and check the validity of the tokens received through each request. This is accomplished with the /oauth/check_token endpoint exposed in the resource server.  If you check the application.properties of the resource server, you can see that we have declared the endpoint with client app details.

security.oauth2.client.client-id=client
security.oauth2.client.client-secret=password

security.oauth2.resource.token-info-uri=http://localhost:9090/oauth/check_token

 

The resource server will extract the token from the request and check the validity through above endpoint.

 

Accessing the resources with Access Token

Here i have assumed that the authorization server and resource server is already up and running.

since the /public endpoint is permitted to access for all, we should be able to access it without any access token.

Screen Shot 2019-05-25 at 11.03.58 AM.png

 

Now we will try to access the  /admin endpoint without any token. Since our request is not authenticated (does not contain any token), It should not allow us to access the resource. As you can see that we got 401 unauthorized error.

Screen Shot 2019-05-25 at 11.14.59 AM.png

 

Now it is clear that we should have a valid access token to access the /admin resource. lets try to generate an access token based on some user credentials.

username : user

password : password

Screen Shot 2019-05-25 at 11.11.51 AM.png

 

Now we will use the generated access token to access the /admin endpoint.  Here you can see that we have got a different error with different error code.  This is because token will claim only for the ROLE_USER privilege.  In order to access the /admin resource, the token with authority ROLE_ADMIN is required.

Screen Shot 2019-05-25 at 11.14.34 AM.png

 

Lets re-generate the access token with admin credentials.

Screen Shot 2019-05-25 at 11.22.20 AM.png

 

Now we will access the /admin endpoint with access token generated using admin user credentials. Yes! we are done.

Screen Shot 2019-05-25 at 11.26.21 AM.png

 

The Source Code

The Source code of the Resource Server can be found at GitHub. Click here to download it.

 

Microservices: How to use Spring Security OAuth2 to Secure Spring REST Api (Authorization Server with In-memory set up) – Part 2

This is the Part 2 of the series of articles written to share my experience on securing REST Api(s) with Spring Security OAuth2.  The other pars of this article series have been listed below.

Part 1 :  Basics of OAuth2, Roles, Grant types and Microservices security.

Part 2 :  Setting up Authorization server with Spring Security OAuth2 using In-memory token store and client details

Part 3 :  Setting up Resource Server with Spring Security OAuth2.

Part 4 :  Enhancing Authorization server to store client app details and tokens in the database (JDBC client and token store)

Part 5 :  Secure REST Api with Spring Security OAuth2 using JWT token

Part 6 :  Token Revoke and Invalidating

 

Here we will be focusing on how to implement Authorization server to handle client registration and token issuing using in-memory mechanism.

 

Setting up Authorization server

 

You can create a spring boot based project for Authorization server is as follows. Make sure that you have added the Web, OAuth2-Cloud and Spring Security dependencies correctly.

Screen Shot 2019-05-22 at 11.43.10 PM.png

 

once the project is generated, make sure that the following dependencies exist in the pom.xml.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

 

 

Once the project is generated, we can add the WebSecurity Configuration as follows.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password(passwordEncoder.encode("secret")).roles("USER");
auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder.encode("secret")).roles("ADMIN");
}
}

 

The Authorization server will authenticate users and issue tokens to access the protected resources.  Since the authorization server does not maintain/expose any resources, we have nothing to secure here. Therefore we haven’t  declared the HTTP or Web Security configurations here. we have created only the authentication-manager.  The users will be authenticated against the in-memory user details store implemented.

 

Adding Authorization Server Configuration 

We have added the Authorization server configuration as follows.


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.password.PasswordEncoder;
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.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenStore tokenStore;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("client")
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
.scopes("read", "write")
.autoApprove(true)
.secret(passwordEncoder.encode("password"));
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.tokenStore(tokenStore);
}
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.checkTokenAccess("isAuthenticated()");
}
}

 

clients.inMemory() specifies that we are going to store the services in memory. In a ‘real’ application, we would save it in a database, an LDAP server.As you can see that we have registered one client application in memory.

authorizedGrantTypes – This specifies what are the possible authorization grant types supported by the client application being registered. For this article, we will be using only the password grant type. 

Spring Security OAuth exposes two endpoints for checking tokens (/oauth/check_token and /oauth/token_key). Those endpoints are not exposed by default (have access “denyAll()”).  You can enable those endpoints for authenticated client applications as follows.

oauthServer.checkTokenAccess("isAuthenticated()");

You may add “permitAll()” instead of  “isAuthenticated()

 

Running the Authorization Sever

Now we have done the required configuration for the OAuth2 Authorization server. lets run it and check whether it is working.

mvn spring-boot:run

The server will be up and running on port 9090.

 

Generating Access Token and Refresh Token

The following endpoint can be used to generate the access token and refresh token.

POST  /oauth/token

 

First we need to use the client application credentials to authenticate with Authorization server. Then we can use the user credentials to generate an access token and refresh token for accessing the protected resource.  Please refer the below screenshots.

  • Authenticate using client app credentials

username : client

password :  password

Screen Shot 2019-05-24 at 9.21.31 PM.png

  • Generate access token for the user credentials. 

 

Screen Shot 2019-05-24 at 9.21.42 PM.png

 

You can see that access token and refresh token are generated correctly.

 

Checking and Verifying the Generated Token

You can use the following endpoint to check and verify the generated token.

POST  /oauth/check_token

 

This can be done as follows.

  • Authenticate with client app credentials

username : client

password :  password

Screen Shot 2019-05-24 at 9.30.28 PM.png

 

  • Sending the generated token for retrieving the details. 

Screen Shot 2019-05-24 at 9.32.20 PM.png

You can see that the response contains client app id, scopes, user and authorities/roles.

In the next part, we will look at how to set up resource server to keep protected resources and authorize the access to the protected resources only for the valid/authorized tokens.

 

Source Code

The completed source code of this article can be found at GitHub. Click here to download it.

 

Spring Boot Test and Spring Security: Perform Http Basic Authentication with TestRestTemplate

 

What is HTTP Basic Authentication?

If you want to refresh your knowledge on HTTP Basic Authentication, please click here to refer my article on that.

Here i am going to show you how to execute spring test cases on REST endpoints that are secured with Spring Security and required HTTP Basic Authentication.  Here we are going to use the TestRestTemplate as the REST client for invoking REST endpoints.

 

TestRestTemplate

TestRestTemplate is a convenience alternative to Spring’s RestTemplate that is useful in integration tests. If you use the @SpringBoootTest annotation , with one of the following webEnviroment attribute, you can use fully configured TestRestTemplate in your Test class.

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
                        OR
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)

 

There are different ways that can be used to perform Basic Authentication with TestRestTemplate.

  1.  Authentication headers
  2.  ‘withBasicAuth’ method
  3.  With Authenticated TestRestTemplate object.

Lets look at each of those approaches in detailed as follows.

Continue reading “Spring Boot Test and Spring Security: Perform Http Basic Authentication with TestRestTemplate”

Spring Boot Test: Writing Unit Tests for the Controller Layers with @WebMvcTest

 

Unit Tests and Integration Tests

@SpringBootTest annotation will load the fully ApplicationContext. Therefore it is highly used for writing the integration testing in web server environment. This will not use slicing and scan for all the stereotype annotations (@Component@Service, @Respository and @Controller / @RestController) and loads the full application context. Therefore this is more good at in the context of writing integration testing for the application.

@WebMvcTest annotation will load only the controller layer of the application. This will scan only the @Controller/ @RestController annotation and will not load the fully ApplicationContext. If there is any dependency in the controller layer (has some dependency to other beans from your service layer), you need to provide them manually by mocking those objects.

Therefore @SpringBootTest is widely used for Integration Testing purpose and @WebMvcTest is used for controller layer Unit testing.

Continue reading “Spring Boot Test: Writing Unit Tests for the Controller Layers with @WebMvcTest”

Swagger for documenting your Spring Boot REST Api

 

What Is Swagger?

Swagger is a set of open-source tools built around the OpenAPI Specification that can help you design, build, document and consume REST APIs.

Swagger  is mostly used as an open source project for describing and documenting RESTful APIs.  Swagger-UI an another tool which provides the capability of displaying the REST Api documentation in the browser.  Besides rendering documentation, Swagger UI allows other API developers or consumers to interact with the API’s resources without having any of the implementation logic in place.

The more details can be found through following documentations.

https://swagger.io/docs/ 

http://springfox.github.io/springfox/docs/current/

 

Springfox for Swagger

The Swagger 2 specification, which is known as OpenAPI specification has several implementations. Currently, Springfox that has replaced Swagger-SpringMVC (Swagger 1.2 and older) is popular for Spring Boot applications.

Continue reading “Swagger for documenting your Spring Boot REST Api”

Spring Security : DelegatingFilterProxy

 

In Spring Security, a request for a protected resource, will go through a chain of spring security filters for fulfilling Authentication and Authorization requirements.

You might be little bit confused about how your web application is interacting with spring security for authentication and authorization purposes.  you might be questioning yourself about following facts. Continue reading “Spring Security : DelegatingFilterProxy”

Spring Security: Method Level Security @Secured, @RolesAllowed and @PreAuthorize/@PostAuthorize

 

One of the great feature in spring security is, it has the ability of providing both URL based security and method level security.  All these annotations – @Secured , @RolesAllowed, @PreAuthorize / @PostAuthorize are used to  achieve the method level security.

The complete code of this article can be found at GitHub

 

AbstractSecurityInterceptor

We will refresh our knowledge about spring security authorization. In spring security, the initial authorization for the user request will be handled by the AbstractSecurityInterceptor.

Continue reading “Spring Security: Method Level Security @Secured, @RolesAllowed and @PreAuthorize/@PostAuthorize”

Spring Security 5 : HTTP Basic Authentication example

How Basic Authentication works in Spring Security?

I have already described the Spring Security Authentication Architecture in a previous article.  So i am not going to repeat the same thing again in this article. If you do not know about the general authentication architecture of spring security, it is highly recommend to take a look at article about Spring Security Authentication Architecture before continue with this article.

Here it is expected to point out the major components and classes that are related to HTTP Basic authentication. Here is the architectural flow of HTTP Basic Authentication implementation in spring security.

How to configure Spring Security for HTTP Basic Authentication?

When you use the httpBasic() configuration element (In HttpSecurity configuration), Spring Security  BasicAuthenticationFilter comes into action.

In Spring Security, the following two classes are the main core (important) classes that supports to implement HTTP Basic Authentication.

  • BasicAuthenticationFilter
  • BasicAuthenticationEntryPoint

A BasicAuthenticationEntryPoint strategy will be configured into the ExceptionTranslationFilter on startup.

Continue reading “Spring Security 5 : HTTP Basic Authentication example”