【问题标题】:Authenticate user with Spring Security使用 Spring Security 对用户进行身份验证
【发布时间】:2020-04-16 05:41:48
【问题描述】:

假设我们有这样的端点 /users/{userId}/messages/{messageId} 并通过 @DeleteMapping 公开(如端点建议的那样,它会删除指定用户的具有指定 ID 的消息)。 Message 可以在两种情况下被删除:您是版主,或者您是消息的所有者。第一部分很简单,你可以添加Security configuration,你需要ROLE_MODERATOR来使用这个endint。但是还有第二种情况,如果您是所有者,则可以删除消息。如何正确实施?如果您在 Security configuration 中添加 ROLE_MODERATOR,您将禁用非版主用户(包括一些消息所有者)的 enpoint。 假设我们有名为AuthenticatedUserHolder 的服务,其方法为getLoggedUserID(),它将返回userID(会话、JWT 或某事)。有什么方法可以结合ROLE_MODERATOR 或消息所有者?
第二个问题:假设我们有端点/users/{id}/addresses@PutMapping,并且只有loggedUserID == id 才能更改地址。如何从service/facade 中提取逻辑,如果loggedUserID != id 将返回401/403

编辑:方法代码:

SecurityContext authentication = SecurityContextHolder.getContext();
    UserPrincipal loggedUser = (UserPrincipal) authentication.getAuthentication().getPrincipal();
    return loggedUser.getUser().getPersonId();

UserPrincipal 有额外的字段personId

【问题讨论】:

    标签: spring spring-boot authentication spring-security


    【解决方案1】:

    您可以将@PreAuthorize 注释与自定义方法一起使用 Examples

    控制器

    @PreAuthorize("@beanName.beanMethodName(#controllerParamName)")
    @GetMapping("/{controllerParamName}")
    fun getMethod(@PathVariable("controllerParamName") param: Long) {
        //whenever
    }
    

    验证 Bean

    @Service
    class BeanName {
       fun beanMethodName(param: Long): Boolean {
          return false
       }
    }
    

    【讨论】:

    • 一切看起来都很好,但是当我试图通过服务从Authentication 获取loggedUserId 时出现错误:Attempted to call method loggedUserId() on null context object。看起来Authentication 不是在处理@PreAuthorize 注释之前构建的。我已经提出了方法代码的问题。编辑:不,看起来Spring Context 根本没有构建。就像在构建整个上下文之前调用 @PreAuthorize 一样。我如何使用@PreAuthorize 中的组件?
    猜你喜欢
    • 2011-08-12
    • 1970-01-01
    • 2011-08-21
    • 2012-11-27
    • 2019-12-26
    • 1970-01-01
    • 2017-12-21
    • 2016-07-17
    相关资源
    最近更新 更多