Implement Authentication and Authorization based spring security

Posted By : Yash Arora | 01-Jul-2018

In this blog, I am going to explain how to implement spring security in your project.
First of all, we can use two types of security 
1.Authentication
2.Authorization

Authentication:-Authentication is simple kind of security like login in which only those user can access the application who is registered with the application.

Authorization:-Authorization is basically provided access/privileges to the user according to his roles. Superadmin can have all kind of privileges like block user, disapprove KYC etc.


Let's start with the Authentication:-
Spring Security also provide its  /login API where you can enter your username and password that you have entered during registration
. It will authenticate whether you are a valid user or not.

But make sure that variable names that you have entered during registration must be  the same as during login.
What happens when we hit login API provided by spring security It will make a call of method loadUserByUserName provided by us in a custom class that implements UserDetailsService and it will return User object. This user class is itself provided by spring security. Don't confuse it with your user class.

           @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //username value comes from login api
        com.scaffold.domain.User applicationUser = applicationUserRepository.findByEmail(username);//email
        if (applicationUser == null) {
            throw new UsernameNotFoundException(username);
        }
        return new User(applicationUser.getEmail(), applicationUser.getPassword(), emptyList());
    }
      

You can create your own login API to authenticate the user.


Let's move to Authorization part:-
In this  I am going to explain method based authorization.To secure any api we have to use @PreAuthorize(hasAnyRole("addAdmin")) on the method we want to secure.

Create a class SecurityConfiguration that extends WebSecurityConfigurationAdapter.

          @EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
	http.cors().and().csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, REGISTER_URL).permitAll()
	.antMatchers(HttpMethod.POST, LOGIN_URL).permitAll().antMatchers(HttpMethod.GET, VERIFICATION_URL)
	.permitAll().antMatchers(HttpMethod.DELETE, LOGOUT_URL).permitAll()
        .and().anyRequest().authenticated().
        .addFilter(new JWTAuthorizationFilter(authenticationManager(),getApplicationContext()))
	.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}
      

We are using JwtAuthorizationFilter which will do role based authorization work.

We are providing activities to subadmin during its creation by selecting checkboxes from frontend. That activities will be passed to redis server when user successfully loggedin.
Now in JwtAuthorizationFilter we will get all the activities for that particular user from redis server and provide those activities to SimpleGrantedAuthority class.

         if (activities != null) {
	 for (String actitvity : activities) {
	   authoritiesProvidedToUser.add(new SimpleGrantedAuthority("ROLE_" + actitvity));
	 }
	}
         return new UsernamePasswordAuthenticationToken(user, null, authoritiesProvidedToUser);
      

Now if activity provided to user is addAdmin and one of the method have @PreAuthorize(hasAnyRole("addAdmin)) then it will access the api otherwise api response wil be access denied. It works fine for single microservice.The problem occured when we are dealing with different microservice and other microservice have also @PreAuthorize annotation.How we will do it. The solution will be we would use HeaderMapRequestWrapper and we will provide all the activities in request parameter that request should be move in other microservice spring security class and will get all the activiities from that request.

       requestWrapper = new HeaderMapRequestWrapper(request);
	requestWrapper.addHeader("activities", finalActivities);
       chain.doFilter(requestWrapper,response)
      

Create other class in other microservice and extend that class with BasicAuthentication and implement dofilter(HttpServlet req,HttpServlet res) method. Do the same work as done in this microservice jwtauthorizationFilter class.

 

 

About Author

Author Image
Yash Arora

Request for Proposal

Name is required

Comment is required

Sending message..