Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support AuthoritiesProvider for Resource Server flows (opaque and jwt) #160

Open
bdemers opened this issue Feb 6, 2020 · 8 comments
Open

Comments

@bdemers
Copy link
Contributor

bdemers commented Feb 6, 2020

Currently, the AuthoritiesProvider interface only supports authorization code flow and not resource servers.

We should be able to add a new method or two in AuthoritiesProvider to support resource servers.

@bdemers
Copy link
Contributor Author

bdemers commented Feb 6, 2020

NOTE: As part of this change it should be possible, to lookup and use the JwtAuthenticationConverter bean instead of explicitly setting the OktaJwtAuthenticationConverter

@paulorego
Copy link

Hi, is there any way to add custom authorities on resource servers using JWT and OKTA?

@bdemers
Copy link
Contributor Author

bdemers commented Jan 18, 2022

@paulorego Currently you would need to do something like this:

https://github.com/okta/okta-spring-boot/blob/master/oauth2/src/main/java/com/okta/spring/boot/oauth/OktaOAuth2ResourceServerAutoConfig.java#L63-L68

However, some of those classes are package protected, so they would need to be wrapped (with something like a BeanPostProcessor 😢), or re-implemented.

@swargolet
Copy link

@bdemers How would this bean get picked up? Looking at OktaOAuth2Configurer (https://github.com/okta/okta-spring-boot/blob/master/oauth2/src/main/java/com/okta/spring/boot/oauth/OktaOAuth2Configurer.java#L155-L156), it doesn't use the JwtAuthenticationConverter bean but instantiates a new one.

Is there something I'm missing here? We are also trying to add our own authorities but haven't been able to.

bdemers added a commit that referenced this issue Jan 27, 2022
NOTE: This doesn't work, I was just putting thoughts down, and it ended up being a be more complicated:

TODO:
* There is probably a better Spring Security abstraction for all of this
* Need to check to see if returning a `Converter` bean will inject correctly everywhere (including with native images)
* Need to implement something similar for opaque tokens
* Need to add tests that will make sure scope authorities and claim/group authorities are merged correctly
* The new method in AuthoritiesProvder's return type doesn't match the other very related method in this interface (and it still doesn't cover the opaque token use case)

Related: #160
@bdemers
Copy link
Contributor Author

bdemers commented Jan 27, 2022

@swargolet good catch, I guess I was typing faster than thinking 😄

I started writing a reply, but then figured it would be easier to try to hack something up, I was wrong...
But it was still useful to figure out what it will take to add this feature: #405

TL;DR: it's still going to take a bit of work 😞

@swargolet
Copy link

swargolet commented Jan 27, 2022

Ended up coming up with a solution around this.
Since the OktaOAuth2Configurer overrides everything after .oauth2ResourceServer() in the security config, we can look one level ahead of that. In this case we can leverage overriding the authProvider and providing our own implementation which has our own converter implementation. See below for the security config.

Only downside to this, which I call out in a comment is that it overrides the OktaJwtAuthenticationConverter and thus the logic in which it pulls the claims in from the token is not utilized.

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private JwtDecoder jwtDecoder;
    private Converter<Jwt, Collection<GrantedAuthority>> myJWTGrantedAuthoritiesConverter;

    @Autowired
    public void setJwtDecoder(JwtDecoder jwtDecoder) {
        this.jwtDecoder = jwtDecoder;
    }

    @Autowired
    public void setMyJWTGrantedAuthoritiesConverter(Converter<Jwt, Collection<GrantedAuthority>> myJWTGrantedAuthoritiesConverter) {
        this.myJWTGrantedAuthoritiesConverter = myJWTGrantedAuthoritiesConverter;
    }

    private Converter<Jwt, AbstractAuthenticationToken> jwtAuthenticationConverter() {
        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(myJWTGrantedAuthoritiesConverter);
        return jwtAuthenticationConverter;
    }

    private AuthenticationProvider authProvider() {
        JwtAuthenticationProvider jwtAuthenticationProvider = new JwtAuthenticationProvider(jwtDecoder);
        Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter = jwtAuthenticationConverter();
        jwtAuthenticationProvider.setJwtAuthenticationConverter(jwtAuthenticationConverter);
        return jwtAuthenticationProvider;
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .anyRequest()
                .authenticated()
            .and()
                .authenticationProvider(authProvider()) // This overrides OktaJwtAuthenticationConverter and this we lose claims to Authorities functionality
                .oauth2ResourceServer()
                    .jwt()
        ;
    }
}

@bdemers
Copy link
Contributor Author

bdemers commented Jan 28, 2022

Thanks for following up!

@Sam-Bate-ITV
Copy link

why is this closed as completed if the related PR was not merged and the problem remains in the latest release? Please can this be reopened.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants