簡體   English   中英

Spring 安全性:使用數據庫中的角色登錄

[英]Spring security: log in using roles from database

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

我想為具有特定角色的用戶授予對特定頁面的訪問權限。

我有這個 class 我在其中配置了安全性:

@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 我應該如何告訴SpringROLE表的role_name列中查找用戶角色?

它工作正常嗎?

不,您在.authoritiesByUsernameQuery方法參數中有錯誤的查詢字符串。

查詢返回類型,即結果集應該是用戶名和角色

SELECT username, role

如果連接查詢的結果集列名如下所示:

在此處輸入圖像描述

您應該修改為如下所示:

在此處輸入圖像描述

通過使用別名SELECT ud.username AS username, rm.name AS role

我試過這個:antMatchers("/mypage").hasRole("MODERATOR") 但它拋出 403 錯誤

它不起作用,因為您的授權部分不正確。

我應該如何告訴 Spring 從 ROLE 表的 role_name 列中查找用戶角色?

它需要完整的身份驗證和授權配置。 請參閱下面的相同內容。

我將給出一個工作示例:

考慮您的要求具有類似的三個表userdetailsrolemasteruser_role_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();
    }

}

授權部分
通過對存儲在資源文件夾中的 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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM