![](/img/trans.png)
[英]Spring Security - GrantedAuthority and role-based access
[英]spring security - role based access
我已經為我的 webapp 實現了 spring 安全。
我想配置基於角色的訪問。 只有具有“ROLE_ADMIN”角色的用戶才能登錄。
我添加了模型“角色”並在我的數據庫中添加了一個表。 但是,具有“ROLE_USER”角色的用戶仍然可以登錄。
@Override
protected void configure(HttpSecurity http) {
try {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/resources/**").hasRole("ROLE_ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
} catch (Exception e) {
e.printStackTrace();
}
}
謝謝!
編輯:完整的彈簧安全配置
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = UserDetailsServiceImpl.class)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/css/**", "/js/**");
}
@Override
protected void configure(HttpSecurity http) {
try {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/resources/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
} catch (Exception e) {
e.printStackTrace();
}
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(bCryptPasswordEncoder());
return authProvider;
}
@Autowired
public void globalSecurityConfiguration(AuthenticationManagerBuilder auth) {
try {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
} catch (Exception e) {
e.printStackTrace();
}
}
}
你在擴展WebMvcConfigurerAdapter
嗎? 此外,hasRole 會將提供的字符串前綴為“ROLE_”
來自文檔:
需要的角色(即用戶、管理員等)。 請注意,它不應以“ROLE_”開頭,因為這是自動插入的。
例子:
@SpringBootApplication
public class SampleWebSecureJdbcApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(SampleWebSecureJdbcApplication.class).run(args);
}
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/about").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login").failureUrl("/login?error").permitAll()
.and()
.logout().permitAll();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(this.dataSource);
}
}
}
我已經實現了一個基於角色的訪問,登錄后管理員用戶將被定向到管理員主頁,普通用戶將被重定向到用戶主頁。
下面是我的 SecurityConfiguration 類。
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
final String sqlUserName = "select email, password, active from user where email=?";
final String sqlAuthorities= "select u.email, r.role from user u inner join user_role ur on(u.user_id=ur.user_id) inner join role r on(ur.role_id=r.role_id) where u.email=?";
auth.
jdbcAuthentication()
.usersByUsernameQuery(sqlUserName)
.authoritiesByUsernameQuery(sqlAuthorities)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http. authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/resources/**", "/static/**", "/static.css/**", "/js/**", "/static.images/**").permitAll()
.antMatchers("/user").hasAuthority("USER")
.antMatchers("/home").hasAuthority("ADMIN").anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/loginroute",true)
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied");
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/static.css/**", "/js/**", "/static.images/**");
}
}
.defaultSuccessUrl("/loginroute",true)將重定向到 /loginroute 控制器。 下面是控制器方法。
@RequestMapping (value = "/loginroute",method = RequestMethod.GET)
public String sample(){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
String rolevalue = null;
for (Role role : user.getRoles()) {
rolevalue = role.getRole();
}
System.out.println(user.getRoles().contains("role"));
if(rolevalue.equals("ADMIN"))
return "redirect:home";
else if(rolevalue.equals("USER"))
return "redirect:user";
return "User does not have permission";
}
@RequestMapping(value="/home", method = RequestMethod.GET)
public ModelAndView home(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("userName", "Welcome " + user.getName() + " " + user.getLastName() + " (" + user.getEmail() + ")");
modelAndView.addObject("adminMessage","Content Available Only for Users with Admin Role");
modelAndView.setViewName("home");
return modelAndView;
}
@RequestMapping(value="/user", method = RequestMethod.GET)
public ModelAndView userhome(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("userName", "Welcome user: " + user.getName() + " " + user.getLastName() + " (" + user.getEmail() + ")");
modelAndView.addObject("userMessage","Content Available Only for Users with User Role");
modelAndView.setViewName("user");
return modelAndView;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.