java - 基于 Spring Security 角色的访问限制
问题描述
我是 Spring Security 的新手。根据我对教程的理解,我们将在 antMatcher 中配置用户角色。
我的问题是,如果admin
已登录,它是否从上下文中识别 URL/admin
并允许权限?如果是这样,我必须为/admin/operation
和编写基于个人角色的方法/user/operation
。但是,除了上下文级别的实现,我如何限制用户。
换句话说,我应该/operation
在操作中只有一种方法,我应该识别用户角色并且必须执行基于角色的操作。
如何做到这一点?
请帮忙...
解决方案
您只需要使用需要身份验证的 antMatchers() 方法定义资源 URL 列表。具有特定角色的用户将能够访问资源,而无需为其他角色做任何事情。下面我为 HTTP Basic 和 Form Based Authentication 定义了两种配置。
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String REALM_NAME = "startwithjava.com";
@Configuration
@Order(1)
public static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
LoggingAccessDeniedHandler accessDeniedHandler;
@Autowired
AuthSuccessHandler authSuccessHandler;
@Autowired
AppUserDetailsService appUserDetailsService;
@Autowired
PasswordEncoder passwordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(
"/",
"/js/**",
"/css/**",
"/img/**",
"/webjars/**").permitAll()
.antMatchers("/user/**").hasRole("USER")
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.successHandler(authSuccessHandler)
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(appUserDetailsService);
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
auth.authenticationProvider(daoAuthenticationProvider);
}
}
@Configuration
@Order(2)
public static class ApiTokenSecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
AppUserDetailsService appUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/api/**")
.hasRole("ADMIN")
.and()
.httpBasic()
.realmName(REALM_NAME)
.authenticationEntryPoint(new ApiAuthenticationEntryPoint())
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(appUserDetailsService);
auth.authenticationProvider(daoAuthenticationProvider);
}
}
}
推荐阅读
- c++ - 类中的 C++ 2d“动态”数组?
- java - PriorityQueue (Java),用 Long 覆盖比较器
- python - 字节数组引用与值类型?
- html - 如何在不同的分辨率下将几个元素保持在同一位置
- ios - iOS 应用被拒绝,因为订阅在模拟器上不起作用
- c# - Unity2D:使用 UI 按钮移动播放器 - 平滑动画
- c++ - BGL:当包含 random_spanning_tree.hpp 时,对 strong_components 的调用无法编译
- android - 用户比 Cloud Function 更快
- python - 从 BIG CSV 文件 Python 中删除一行
- f# - F# / 在编译时验证数组长度的最简单方法