我正在开发一个Spring Boot应用程序,并为用户编写了一个API,使其能够阅读消息。 URL之一是:
/users/USER1/messages
现在,我显然希望仅通过身份验证的用户才能访问此get请求的内容。但是所有经过身份验证的用户还不够。我还希望只有拥有用户名的用户-USER1可以在此处查看真实内容,其余用户应该获得403状态。我想出了没有spring安全配置的方法(在我的服务中,我正在检查登录的用户名,并将其与URL中的参数进行比较,仅当它们相等时才进行操作),但是我认为应该有一种更简单的方法仅使用SecurityConfiguration?我当前的配置如下所示:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/users/**").authenticated()
.antMatchers("/h2-console/*").permitAll()
.anyRequest().authenticated()
.and()
.formLogin();
http.csrf().disable();
http.headers().frameOptions().disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("superman").password("superman").roles("USER")
.and()
.withUser("admin").password("admin").roles("ADMIN");
}
}
编辑:以下提示建议使用方法安全性表达式的答案我已经使用过,但是它似乎仍然无法正常工作(如果我通过USER2身份验证,我仍然可以读取USER1的消息)。这是我添加了PreAuthorize批注的控制器
@RequestMapping(method = RequestMethod.GET, value = "/messages", produces = {"application/json"})
@ResponseBody
@PreAuthorize("#userHandle == authentication.name")
public List<Message> getMessages(@PathVariable("userHandle") String userHandle,
@RequestParam(value="search", defaultValue="") String search) {
//todo: change to return DTO not model
return messageFacade.getMessages(userHandle, search);
}
EDIT2:如接受答案中的注释中所示,@ EnableGlobalMethodSecurity(prePostEnabled = true)需要包含在安全配置中。一旦包括在内,一切都将正常工作。
最佳答案
我认为您需要Spring Method Security。文档中的示例几乎就是您的情况:
import org.springframework.data.repository.query.Param;
...
@PreAuthorize("#n == authentication.name")
Contact findContactByName(@Param("n") String name);
PS:别忘了
@EnableGlobalMethodSecurity
!参见教程here