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

我在 db: 中有 3 个表USER(login,password)ROLE(role_name)并且USER_ROLE_LINK (user_id, role_id)

我想为具有特定角色的用户授予对特定页面的访问权限。

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

@Configuration

@EnableWebSecurity

public 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


Helenr
浏览 60回答 1
1回答

回首忆惘然

效果好吗?不,方法参数中的查询字符串错误.authoritiesByUsernameQuery。查询返回类型即结果集应该是用户名和角色SELECT username, role如果连接查询结果结果集列名称如下所示:您应该修改为如下所示:通过使用别名SELECT ud.username AS username, rm.name AS role我试过这个: antMatchers("/mypage").hasRole("MODERATOR") 但它抛出 403 错误它不会工作,因为您的授权部分不正确。我应该如何告诉Spring从ROLE表的role_name列中查找用户的角色?需要完整的认证和授权配置。请参阅下面的相同内容。我将举一个可行的例子:考虑您的要求具有类似的三个表userdetails、rolemaster、 和 ,user_role_mapping如下所示。那么你的配置将是@Configuration@EnableWebSecuritypublic 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.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java