【问题标题】:Using both Realm roles and ressource roles with Keycloak/SpringSecurity将领域角色和资源角色与 Keycloak/Spring Security 一起使用
【发布时间】:2020-05-25 14:12:44
【问题描述】:

我正在尝试在带有 spring-security 和 keycloak 的 java 应用程序中同时使用领域和资源角色。不幸的是,keycloak 只会根据 :

的值返回一个或另一个
keycloak.use-resource-role-mappings=true

您仍然可以使用自定义代码来获得两者,但它会弄乱诸如@PreAuthorize 或spring-boot 方法.isUserInRole 之类的注释,从而导致代码丑陋。

有没有办法覆盖@PreAuthorize 方法或Keycloak 返回的JSON 令牌,以便同时使用领域和资源角色?目前,我的 keyclaok 实现使用自定义方法替换每个方法开头的 @PreAuthorize,它并不漂亮。

提前谢谢你。

【问题讨论】:

  • 你写了什么样的自定义代码弄乱了注释?您应该能够通过编写自定义 JwtAuthenticationConverter (docs.spring.io/spring-security/site/docs/current/api/org/…) 从存储在 JWT 中的领域和资源角色填充 GrantedAuthority 来实现您想要的
  • 对不起,我对此不是很清楚,注释很好,但它们不可用,因为它们只包含一半的角色,我会尝试覆盖 Jwt 以获得干净解决方案我也在尝试以@PreAuthorize("@KeycloakAuthorize.hasKeycloakRole('role')") 的格式在预授权中使用bean,但到目前为止也没有成功
  • 好的,那么 JwtAuthenticationConverter 可能是您最好的选择,因为您可以简单地访问 JWT 并根据需要填充权限,例如:stackoverflow.com/questions/58205510/…
  • 我会试试这个并发布解决方案,如果它有效,谢谢:)
  • Np,让我知道它是否有效! :)

标签: java spring-security realm keycloak


【解决方案1】:

当我在 SecurityConfig 中使用它时,让它覆盖 KeycloakAuthenticationProvider。这是自定义提供程序的代码

public class CustomKeycloakAuthenticationProvider extends KeycloakAuthenticationProvider {
    private GrantedAuthoritiesMapper grantedAuthoritiesMapper;

    public void setGrantedAuthoritiesMapper(GrantedAuthoritiesMapper grantedAuthoritiesMapper) {
        this.grantedAuthoritiesMapper = grantedAuthoritiesMapper;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        KeycloakAuthenticationToken token = (KeycloakAuthenticationToken) authentication;
        List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();

        for (String role : token.getAccount().getRoles()) {
            grantedAuthorities.add(new KeycloakRole(role));
        }

// ADDING THE MODIFICATION AND ENABLING ROLE FROM RESSOURCE

        for (String role : token.getAccount().getKeycloakSecurityContext().getToken().getResourceAccess("CustomApplication").getRoles()) {
            grantedAuthorities.add(new KeycloakRole(role));
        }
        return new KeycloakAuthenticationToken(token.getAccount(), token.isInteractive(), mapAuthorities(grantedAuthorities));
    }

    private Collection<? extends GrantedAuthority> mapAuthorities(
            Collection<? extends GrantedAuthority> authorities) {
        return grantedAuthoritiesMapper != null
            ? grantedAuthoritiesMapper.mapAuthorities(authorities)
            : authorities;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return KeycloakAuthenticationToken.class.isAssignableFrom(aClass);
    }


}

以及SecurityConfig中的修改

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        CustomKeycloakAuthenticationProvider keycloakAuthenticationProvider = CustomKeycloakAuthenticationProvider();
        keycloakAuthenticationProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(keycloakAuthenticationProvider);
    }

    private CustomKeycloakAuthenticationProvider CustomKeycloakAuthenticationProvider() {
        return new CustomKeycloakAuthenticationProvider();
    }

感谢亚历山大的帮助!

【讨论】:

  • 谢谢@Taarawa。它帮助我解决了使用领域角色的问题。
猜你喜欢
  • 2011-04-12
  • 2021-02-05
  • 1970-01-01
  • 2020-08-27
  • 2023-01-11
  • 2015-07-29
  • 2018-10-03
  • 1970-01-01
  • 2011-03-12
相关资源
最近更新 更多