java - 使用 Spring Security 按角色限制 api 功能
问题描述
我正在尝试在我的项目中实现 SpringSecurity 机制。我有两个角色:成员和管理员。MEMBER 和 ADMIN 都可以访问 api 更新用户,例如。MEMBER只能改名字,头像,ADMIN什么都可以改。我如何应用 SpringSecurity 概念来做到这一点?
解决方案
您首先需要为每个角色提供两个不同的用户。例如,以下将提供用户的内存表示member
,并且admin
每个都有密码password
:
@Bean
static InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("member")
.password("password")
.roles("MEMBER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
现在您可以设置授权规则。对于您希望任一角色起作用hasAnyRole(...)
的 URL,您可以使用,对于您只想与您可以使用的管理员一起使用的 URL hasRole(...)
。例如,以下内容将允许任一用户使用 URL /user/name
,或者/user/avatar
管理员可以使用任何以 . 开头的 URL /user/**
。所有其他 URL 均被拒绝。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/user/name", "/user/avatar").hasAnyRole("MEMBER", "ADMIN")
.mvcMatchers("/user/**").hasRole("ADMIN")
.anyRequest().denyAll()
.and()
.formLogin();
}
}
需要注意的是,只有第一条规则将用于授权。因此,当/user/name
匹配规则/user/name
时,将/user/**' (starts with
使用 /user/ ), and
anyRequest() only the first rule of
hasAnyRole("MEMBER", "ADMIN")`。
您还可以设置利用 HTTP 方法的规则。例如,以下将允许MEMBER
或ADMIN
用于 HTTP GET on/user/address
.mvcMatchers(HttpMethod.GET, "/user/address").hasAnyRole("MEMBER", "ADMIN")
另一种方法是为您的用户分配多个角色。例如,管理员用户可能具有角色MEMBER
和ADMIN
.
@Bean
static InMemoryUserDetailsManager userDetailsManager() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("member")
.password("password")
.roles("MEMBER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("ADMIN", "MEMBER")
.build();
return new InMemoryUserDetailsManager(user);
}
然后,您的规则可以简化为对 URL 具有单一角色。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.mvcMatchers("/user/name", "/user/avatar").hasRole("MEMBER")
.mvcMatchers("/user/**").hasRole("ADMIN")
.anyRequest().denyAll()
.and()
.formLogin();
}
}
当您需要考虑很多角色时,这种方法可能更可取。每个操作都是一个角色,但用户可能拥有多个角色。
推荐阅读
- hibernate - 从 Postman 中的 GraphQL 查询获取数据时出现异常 (/getAccidentsForDriver):null"
- angular - 如何在 StackBlitz 中使用 Angular CLI 示意图
- python - FutureWarning:statsmodels.tsa.arima_model.ARMA 和 statsmodels.tsa.arima_model.ARIMA 已被弃用
- python - 每个时期的训练和验证集?
- jquery-select2 - 使用配置 FormatSelection 设置选定值 Remote Select2
- javascript - 我正在尝试显示输入错误凭据的警报,但仅显示在控制台中
- swift - 应用程序全屏时如何调整文本大小
- ansible - 按自然字母数字顺序在ansible中排序列表
- angular - Angular - 如何在不更改 URL 的情况下使 URL 不区分大小写?
- c++ - C++ getline函数连续循环