我正在尝试在我的项目中实现SpringSecurity机制。我有两个角色:会员和管理员。例如,MEMBER和ADMIN都可以访问api更新用户。会员只能更改姓名、头像,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);
}
现在您可以设置授权规则了。对于希望任何一个角色都能工作的URL,可以使用hasAnyRole(...)
;对于只想与管理员一起工作的URL可以使用hasRole(...)
。例如,以下内容允许用户使用URL/user/name
或/user/avatar
,但管理员可以使用任何以/user/**
开头的URL。所有其他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
在/user/address
上进行HTTP GET
.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();
}
}
当你有很多角色需要考虑时,这种方法可能更可取。每个操作都是一个单独的角色,但用户可能有多个角色。