[英]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
。 我應該如何告訴Spring
從ROLE
表的role_name
列中查找用戶角色?
它工作正常嗎?
不,您在.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
@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.