Java Spring安全性:使用数据库中的角色登录

Java Spring安全性:使用数据库中的角色登录,java,spring,spring-boot,spring-security,authorization,Java,Spring,Spring Boot,Spring Security,Authorization,我在数据库中有3个表:USER(login,password),ROLE(ROLE\u name)和USER\u ROLE\u LINK(USER\u id,ROLE\u id) 我想为具有特定角色的用户提供访问特定页面的权限 我在这个类中配置了安全性: @配置 @启用Web安全性 公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter { @自动连线 私有数据源; @凌驾 受保护的无效配置(HttpSecurity http)引发异常 { http

我在数据库中有3个表:
USER(login,password)
ROLE(ROLE\u name)
USER\u ROLE\u LINK(USER\u id,ROLE\u id)

我想为具有特定角色的用户提供访问特定页面的权限

我在这个类中配置了安全性:

@配置
@启用Web安全性
公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter
{
@自动连线
私有数据源;
@凌驾
受保护的无效配置(HttpSecurity http)引发异常
{
http
.csrf()
.disable()
.授权请求()
.antMatchers(“/”,“/home”).permitAll()
.anyRequest()
.authenticated()
.及()
.formLogin()
.login页面(“/login”)
.permitAll()
.及()
.logout()
.permitAll();
}
@凌驾
受保护的无效配置(AuthenticationManagerBuilder auth)引发异常
{
auth.jdbc身份验证()
.dataSource(数据源)
.passwordEncoder(NoOpPasswordEncoder.getInstance())
.usersByUsernameQuery(“选择登录名、密码、从登录名=?”的用户激活”)
.authoritiesByUsernameQuery(“从用户u内部加入用户\角色\链接用户u上的用户u中选择用户\角色\ id,其中用户登录=?”;
}
}
它工作正常,只有至少拥有一个角色的用户才能访问该应用程序。现在我想为具有特定角色的用户提供访问特定页面的权限,如何做到这一点

我试过这样做:
antMatchers(/mypage”).hasRole(“主持人”)
但它抛出了
403错误。我应该如何告诉
Spring
ROLE
表的
ROLE\u name
列中查找用户的角色

好用吗

否,您在
.authorities ByUsernameQuery
方法参数中有错误的查询字符串

查询返回类型,即resultset应该是用户名和角色

SELECT username, role
如果join查询产生如下所示的resultset列名:

您应修改为,如下所示:

通过使用别名
选择ud.username作为用户名,rm.name作为角色

我试过这个:antMatchers(“/mypage”).hasRole(“主持人”),但它抛出403错误

它将不起作用,因为您的授权部分不正确

我应该如何告诉Spring从ROLE表的ROLE\u name列中查找用户的角色

它需要完整的身份验证和授权配置。请参阅下面的内容

我将给出一个工作示例:

考虑到您的需求具有类似的三个表
userdetails
rolemaster
,以及
user\u role\u mapping
,如下所示

然后您的配置将

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter 
{

    @Autowired
    DataSource dataSource;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception
    {
    //If you want to store plain password you can use NoOpPasswordEncoder
    auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder())
                .usersByUsernameQuery("select username, password, enabled from userdetails where userName=?")
                .authoritiesByUsernameQuery(
                        "SELECT ud.username AS username, rm.name AS role FROM user_role_mapping map " + 
                        "INNER JOIN userdetails ud ON map.userId = ud.id " + 
                        "INNER JOIN rolemaster rm ON  map.roleId = rm.id  where userName = ?");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception
    {
        http
        .authorizeRequests()
            .antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
            .antMatchers("/config/**", "/app/admin/**")
                .hasRole("ADMIN")
            .antMatchers("/app/user/**")
            .hasAnyRole("ADMIN", "USER")
        .and().exceptionHandling().accessDeniedPage("/403")
        .and().formLogin()
            .loginPage("/login")
            .usernameParameter("userName").passwordParameter("password") 
            .defaultSuccessUrl("/app/user/dashboard")
            .failureUrl("/login?error=true")
        .and().logout()
            .logoutSuccessHandler(new CustomLogoutSuccessHandler())
            .invalidateHttpSession(true)
        .and()
            .csrf()
                .disable();

        http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
    }

    @Bean
    public PasswordEncoder passwordEncoder() 
    {
        return new BCryptPasswordEncoder();
    }

}
授权部分
对存储在resources文件夹中的javascript和css等资源的旁路授权

.antMatchers("/resources/**", "/", "/login", "/api/**").permitAll()
用于管理URL

.antMatchers("/config/**", "/app/admin/**").hasRole("ADMIN")
对于可由多个角色访问的URL

.antMatchers("/app/user/**").hasAnyRole("ADMIN", "USER")
.formLogin()
配置:

.usernameParameter("userName").passwordParameter("password") 
// Use above line of code if your login form param names are different 
// than defaults -> "username" "password"
.defaultSuccessUrl("/app/user/dashboard")
// If defaultSuccessUrl not configured then after login success redirects to "/"
异常处理部分

.exceptionHandling().accessDeniedPage("/403")
//If you want custom denied screen to be displayed.

如果您想知道spring security登录身份验证过滤器中的所有默认设置,它还很好地解释了如何配置userDetailsService进行身份验证。谢谢您的回答,但我无法使其工作。在编写时,我将
authorities的参数查询替换为usernameQuery()
方法,现在它返回两列
login
role
,分别包含
admin
admin
。我还添加了
.antMatchers(“/mypage”).hasRole(“ADMIN”)
。和
用户名参数(“登录”);passwordParameter(“密码”)但它仍然不起作用。发布另一个问题,解释您是如何实现的。以及当前的结果和必要的细节。这样我就可以看到你做了什么。我在这里附加的屏幕截图中显示了
角色\管理
。也许你没有注意到这里。