【问题标题】:How to configure Spring Boot Security so that a user is only allowed to update their own profile如何配置 Spring Boot 安全性,以便只允许用户更新自己的配置文件
【发布时间】:2017-08-07 18:13:48
【问题描述】:

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

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

@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
    }}
}

我如何使用 spring security 确保只有用户本身才能更新他的个人资料?任何其他用户都应该被拒绝。有没有一种优雅的方式,如何配置这种行为?

我试图在我的 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();
      }

什么是实现这种行为的好方法?

【问题讨论】:

    标签: spring spring-boot spring-security


    【解决方案1】:

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

    @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

    【讨论】:

      【解决方案2】:

      使用@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属性。

      【讨论】:

        猜你喜欢
        • 2020-11-20
        • 2020-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-12
        • 2018-03-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多