为了账号安全,请及时绑定邮箱和手机立即绑定

Spring security:使用数据库中的角色登录

Spring security:使用数据库中的角色登录

Helenr 2023-09-27 10:15:22
我在 db: 中有 3 个表USER(login,password),ROLE(role_name)并且USER_ROLE_LINK (user_id, role_id)我想为具有特定角色的用户授予对特定页面的访问权限。我在这个类中配置了安全性:@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter{    @Autowired    private DataSource dataSource;    @Override    protected void configure(HttpSecurity http) throws Exception     {        http            .csrf()            .disable()            .authorizeRequests()            .antMatchers("/", "/home").permitAll()            .anyRequest()            .authenticated()            .and()            .formLogin()            .loginPage("/login")            .permitAll()            .and()            .logout()            .permitAll();    }    @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception    {        auth.jdbcAuthentication()            .dataSource(dataSource)            .passwordEncoder(NoOpPasswordEncoder.getInstance())            .usersByUsernameQuery("select login, password, active from USER where login=?")            .authoritiesByUsernameQuery("select ur.user_id, ur.role_id from USER u inner join USER_ROLE_LINK ur on u.id = ur.user_id where u.login=?");    }}它工作正常,只有那些至少拥有一个角色的用户才能访问该应用程序。现在我想为具有特定角色的用户授予特定页面的访问权限,该怎么做?我已经尝试过这个:antMatchers("/mypage").hasRole("MODERATOR")但它会抛出403 error. 我应该如何告诉从表的列Spring中查找用户的角色?ROLErole_name
查看完整描述

1 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

效果好吗?

不,方法参数中的查询字符串错误.authoritiesByUsernameQuery

查询返回类型即结果集应该是用户名和角色

SELECT username, role

如果连接查询结果结果集列名称如下所示:

https://img1.sycdn.imooc.com//651390780001680e02050037.jpg

您应该修改为如下所示:

https://img1.sycdn.imooc.com//651390840001dcdd01830038.jpg

通过使用别名SELECT ud.username AS username, rm.name AS role

我试过这个: antMatchers("/mypage").hasRole("MODERATOR") 但它抛出 403 错误

它不会工作,因为您的授权部分不正确。

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

需要完整的认证和授权配置。请参阅下面的相同内容。

我将举一个可行的例子:

考虑您的要求具有类似的三个表userdetailsrolemaster、 和 ,user_role_mapping如下所示。

https://img1.sycdn.imooc.com//6513909000011aff06530372.jpg

那么你的配置将是


@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()

对于管理员网址


.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.


查看完整回答
反对 回复 2023-09-27
  • 1 回答
  • 0 关注
  • 53 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信