无法在Spring Boot + JWT + MySQL中实现RBAC。

huangapple go评论87阅读模式
英文:

Unable to achieve RBAC with spring boot + JWT +MySQL

问题

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);
    }
}
英文:

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);
}
}

答案1

得分: 2

使用 hasAuthority 或 hasAnyAuthority 方法时,您需要精确匹配权限名称字符串,因此您可能只需要添加 "ROLE_" 前缀,或在配置 WebSecurity.java 中的 Spring Security 时使用 hasRole 和 hasAnyRole 方法。

当创建角色名称时,如果您没有显式添加 "ROLE_" 前缀到角色名称中,Spring 会根据文档为您添加:

默认情况下,如果提供的角色不以 "ROLE_" 开头,将会被添加。可以通过修改 DefaultWebSecurityExpressionHandler 上的 defaultRolePrefix 来自定义此行为。

hasRole 和 hasAnyRole 方法允许您在不使用前缀的情况下指定角色名称:

... 因为我们正在调用 hasRole 方法,所以不需要指定 "ROLE_" 前缀。

您可以在这里查阅 Spring Security 的基于表达式的访问控制文档 链接

英文:

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

huangapple
  • 本文由 发表于 2020年8月25日 03:22:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63567481.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定