使用Spring Security按角色限制api的功能



我正在尝试在我的项目中实现SpringSecurity机制。我有两个角色:会员和管理员。例如,MEMBER和ADMIN都可以访问api更新用户。会员只能更改姓名、头像,ADMIN可以更改任何内容。我如何应用SpringSecurity概念来做到这一点?

您需要从为两个不同的用户提供每个角色开始。例如,以下将提供用户memberadmin的存储器中表示,每个用户都具有密码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 ofhasAnyRole("MEMBER"、"ADMIN"(`。

您还可以设置利用HTTP方法的规则。例如,以下将允许MEMBERADMIN/user/address上进行HTTP GET

.mvcMatchers(HttpMethod.GET, "/user/address").hasAnyRole("MEMBER", "ADMIN")

另一种方法是为用户分配多个角色。例如,管理员用户可能具有角色MEMBERADMIN

@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();
}
}

当你有很多角色需要考虑时,这种方法可能更可取。每个操作都是一个单独的角色,但用户可能有多个角色。

最新更新