如何配置Spring Boot Security,以便仅允许用户更新自己的配置文件

时间:2017-08-06 21:36:23

标签: spring spring-boot spring-security

我已经实现了基本的Spring Boot Security,以保护我的Web服务。我知道您可以仅向某些用户角色授予对某些服务的访问权限,但是是否也可以授予对指定用户的访问权限(用户可以是动态的)?

假设我们有一个社交应用,每个用户都有自己的个人资料。通过以下休息服务,他们应该是唯一能够编辑个人资料的人:

@RestController
public class UserController {
    @RequestMapping(method = RequestMethod.PUT, path = "/user/{userId}", ...)
    public UserDetails updateUserDetails(@PathVariable("userId") String userId) {
        // code for updating the description for the specified user
    }}
}

我如何确保弹簧安全,只有用户自己才能更新他的个人资料?任何其他用户都应该被拒绝。有一种优雅的方式,你如何配置这种行为?

我试图在我的WebSecurityConfig中找到一个方法,但没有成功。

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    // configure authorization for urls
                    .authorizeRequests()
                    // grant access to all users for root path and /home
                    //.antMatchers("/", "/home").permitAll()
                    // here i would like to grant access in the way, that only the user is allowed to perform this request by calling url with his userId
                    .antMatchers(HttpMethod.PUT,"/user/<userId>").and().httpBasic();
      }

实施此行为的好方法是什么?

2 个答案:

答案 0 :(得分:3)

我认为实现这样的事情的最佳方法是将Principal(包含为此请求登录的用户的对象)注入控制器,然后检查用户标识或用户名是否为匹配。

@RestController
public class UserController {
    @RequestMapping(method = RequestMethod.PUT, path = "/user/{userId}", ...)
    public UserDetails updateUserDetails(@PathVariable("userId") String userId, Principal principal) {

        CustomUserDetails userDetails = (CustomUserDetails) principal;
        if (userDetails.getUserId().equals(userId)) {
            // Update the user
        }
    }}
}

请注意,如果要添加用户ID,则需要自定义UserDetails界面,因为默认情况下它仅提供用户名。如果您想知道如何,请查看此question

答案 1 :(得分:3)

使用@PreAuthorize注释:

@PreAuthorize("#userId == principal.userId")
@RequestMapping(method = RequestMethod.PUT, path = "/user/{userId}", ...)
public UserDetails updateUserDetails(@PathVariable("userId") String userId) {
    // code for updating the description for the specified user
}

这假设实现UserDetails接口的类具有userId属性。