0

I am trying to secure our REST end points using the Principal I am getting from our SSO solution.

enter image description here However, I would like to have the values from principal.principal.attributes["perms_claims"] available to the Spring Security "hasAuthority()" SpEL.

I figure, if I could intercept the Principal before it reaches the Spring Controller, I could decorate it so that getAuthorities() method also returns the contents of principal.principal.attributes["perms_claims"].

I'm guessing there is a way to do it using a Spring Interceptor... but I'm not trying to intercept the request itself, but just the principal.

So, how do I intercept a Principal before Spring Web controller request?

Sled
  • 18,541
  • 27
  • 119
  • 168

1 Answers1

1

Good question. Happily, this is covered in the Spring Security reference.

Briefly, though, you'll want to create an OidcUserService delegate:

@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());
    }
}

Note that Spring Security picks up this bean automatically in 5.2.0.RC1. You'll need to wire it directly onto the DSL, as the documentation outlines, in earlier versions.

The strategy for mapping the authorities would probably be something like a single SimpleGrantedAuthority for each permission you identify in your perms_claims attribute.

UPDATE After thinking about this a bit more, I realized that I'd missed a slightly simpler solution, which is using the GrantedAuthoritiesMapper. This solution is a bit more tightly-scoped than the first solution:

@Component
public class MyGrantedAuthoritiesMapper implements GrantedAuthoritiesMapper {
    @Override
    public Collection<? extends GrantedAuthority> mapAuthorities
        (Collection<? extends GrantedAuthority> authorities) {
        // map the authorities
    }
}
Sled
  • 18,541
  • 27
  • 119
  • 168
jzheaux
  • 7,042
  • 3
  • 22
  • 36
  • Thank you. Looking at the documentation I don't know how I'd have recognised it as such without your helpful guidance. – Sled Sep 16 '19 at 18:16