如何拦截一个Spring Principal?

How to intercept a Spring Principal?

我正在尝试使用 Principal I am getting from our SSO 解决方案保护我们的 REST 端点。

但是,我希望 principal.principal.attributes["perms_claims"] 中的值可用于 Spring Security "hasAuthority()" SpEL.

我想,如果我可以在 Principal 到达 Spring 控制器之前拦截它,我也可以 decorate it so that getAuthorities() 方法 returns principal.principal.attributes["perms_claims"] 的内容].

我猜想有一种方法可以使用 ...但我并不是要拦截请求本身,而是拦截主体。

那么,如何在 Spring Web 控制器请求之前拦截 Principal

好问题。令人高兴的是,Spring Security reference.

中对此进行了介绍

不过,简而言之,您需要创建一个 OidcUserService 委托:

@Component
public class MyOidcUserService implements OAuth2UserService<OidcUserRequest, OidcUser> {

    private final OidcUserService delegate = new OidcUserService();

    @Override
    public OidcUser loadUser(OidcUserRequest request) {
        OidcUser user = this.delegate.loadUser(request);
        Collection<GrantedAuthority> authorities = // map the authorities
        return new DefaultOidcUser(authorities, user.getIdToken(), user.getUserInfo());
    }
}

请注意,Spring 安全性会在 5.2.0.RC1 中自动选择此 bean。如文档所述,在早期版本中,您需要将其直接连接到 DSL。

映射权限的策略可能类似于您在 perms_claims 属性中标识的每个权限的单个 SimpleGrantedAuthority

UPDATE 仔细考虑之后,我意识到我错过了 a slightly simpler solution, which is using the GrantedAuthoritiesMapper。这个解决方案比第一个解决方案范围更小:

@Component
public class MyGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper {
    @Override
    public Collection<? extends GrantedAuthority> mapAuthorities
        (Collection<? extends GrantedAuthority> authorities) {
        // map the authorities
    }
}