Ujjwal Mishra
Ujjwal Mishra

Reputation: 177

Unable to achieve RBAC with spring boot + JWT +MySQL

I am developing an API with access to different end points depending on user roles. The API is working but it is not providing Role Based Access as expected. I mean there is no restriction being applied on basis of role, it is working same for different roles. It would be great if someone can be help me figure out the problem. Thanks!

WebSecurity.java

package com.project.techupdate.security;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;


@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    private UserDetailsServiceImpl userDetailsService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public WebSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(HttpMethod.POST,"/file/file-upload").hasAuthority("ADMIN")
                .antMatchers(HttpMethod.POST,"/data/add-data").hasAuthority("ADMIN")
                .antMatchers(HttpMethod.GET,"/data").hasAnyAuthority("ADMIN","USER")
                .antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.parentAuthenticationManager(authenticationManagerBean())
                .userDetailsService(userDetailsService)
                .passwordEncoder(bCryptPasswordEncoder);
    }
}

Upvotes: 2

Views: 307

Answers (1)

Rodrigo Acuna
Rodrigo Acuna

Reputation: 56

When using hasAuthority or hasAnyAuthority methods you need to match the authority name string exactly, so you probably just need to add the "ROLE_" prefix or use hasRole and hasAnyRole when configuring spring security in WebSecurity.java.

When the role name was created if you didn't explicitly add the "ROLE_" prefix to your Role name, spring did it for you according to the docs:

By default if the supplied role does not start with 'ROLE_' it will be added. This can be customized by modifying the defaultRolePrefix on DefaultWebSecurityExpressionHandler.

The hasRole and hasAnyRole methods allow you to address the role name without the prefix:

... since we are invoking the hasRole method we do not need to specify the "ROLE_" prefix.

You can check Spring Security's Expression Based Access control documentation here

Upvotes: 2

Related Questions