grails - 自定义 RoleVoter 并访问 UserRole 进行额外投票检查

标签 grails spring-security

采纳提供的建议here ,我已经实现了自己的 RoleVoter 类来扩展 RoleVoter,并且我需要添加的额外检查是用户、角色和组织都根据我在 session 中存储的组织进行排列。

我有以下 UserRole 类:

class UserRole implements Serializable {
  User user
  Role role
  Organization organization
  ....
}

这是我的 OrganizationRoleVoter 类:

class OrganizationRoleVoter extends RoleVoter {

  @Override
  public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {

    int result = ACCESS_ABSTAIN
    Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication)

    attributes.each {ConfigAttribute attribute ->
      if (this.supports(attribute)) {
        result = ACCESS_DENIED

        authorities.each {GrantedAuthority authority ->
          //TODO this should also check the chosen organization
          if (attribute.attribute.equals(authority.authority)) {
            return ACCESS_GRANTED
          }
        }
      }
    }
    return result
  }

  Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
    return authentication.getAuthorities();
  }

}

正如您在我的 TODO 中看到的,这就是我还需要说的“此处授予的权限也与我在 session 中放置的组织一致。真的不知道如何实现这一目标。

最佳答案

这是迄今为止我解决问题的方法。这似乎有效,但我始终愿意寻求改进:

class OrganizationRoleVoter extends RoleVoter {

  @Override
  public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {

    int result = ACCESS_ABSTAIN
    Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication)
    GrailsWebRequest request = RequestContextHolder.currentRequestAttributes()
    Organization selectedOrganization = (Organization) request.session.getAttribute("selectedOrganizationSession")

    attributes.each {ConfigAttribute attribute ->
      if (this.supports(attribute)) {
        result = ACCESS_DENIED
        for (GrantedAuthority authority : authorities) {
          if (attribute.attribute.equals(authority.authority)) {
            def user = User.findByUsername(authentication.name)
            def role = Role.findByAuthority(authority.authority)
            if (UserRole.findByUserAndOrganizationAndRole(user, selectedOrganization, role)) {
              result = ACCESS_GRANTED
              break
            }
          }
        }
      }
    }
    return result
  }

  Collection<? extends GrantedAuthority> extractAuthorities(Authentication authentication) {
    return authentication.getAuthorities();
  }

}

关于grails - 自定义 RoleVoter 并访问 UserRole 进行额外投票检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10939792/

相关文章:

java - Hibernate - 集合未填充所有子项

spring - 如何在 Spring Security 中获取 AccessDeniedException 的 'reason'/原因?

grails - Grails Spring安全性BootStrap

spring - 如何为 Spring Boot 应用程序设置自定义 Http header "server"

Grails 3 没有包装器?

grails - grails test-app单元测试类未找到被测类的最新版本(找不到符号)

grails - 简单登录页面导致过多的重定向错误

grails - 在NB上运行时出现Grails错误

css - Spring mvc - Css 不起作用

kotlin - 使用 spring-boot-admin-server 时创建名为 `conversionServicePostProcessor` 的 bean 时出错