As context, I've been trying to get a fairly simple @SprintBootApplication with an additional @EnableOAuth2Sso annotation integrated with WSO2 Identity Server for quite some time now.
In my mind getting this working should be a matter of configuration (as advertised on Spring Cloud Security) - but I've had no luck thus far.
In an effort to understand what is going on I've used my debugger to step through spring-security-oauth2 code to figure out what is going on. In doing so I've noticed that my AccessTokenRequest's PreservedState is perpetually null with a resultant CSRF related InvalidRequestException. This is the relevant code:
public class AuthorizationCodeAccessTokenProvider extends OAuth2AccessTokenSupport implements AccessTokenProvider {
....
private MultiValueMap<String, String> getParametersForTokenRequest(AuthorizationCodeResourceDetails resource,
AccessTokenRequest request) {
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
form.set("grant_type", "authorization_code");
form.set("code", request.getAuthorizationCode());
Object preservedState = request.getPreservedState();
if (request.getStateKey() != null || stateMandatory) {
// The token endpoint has no use for the state so we don't send it back, but we are using it
// for CSRF detection client side...
if (preservedState == null) {
throw new InvalidRequestException(
"Possible CSRF detected - state parameter was required but no state could be found");
}
}
When it comes to the above bit of code, I'm at the point where I've approved the claim after having logged in with admin/admin and my web application has received the auth code:
http://localhost:9998/loginstate=Uu8ril&code=20ffbb6e4107ce3c5cf9ee22065f4f2
Given that all I need to do in the first instance is to get the login part working I've tried disabling CSRF, to no avail.
The relevant configuration is as follows:
spring:
profiles: default
security:
oauth2:
client:
accessTokenUri: https://localhost:9443/oauth2/token
userAuthorizationUri: https://localhost:9443/oauth2/authorize
clientId: yKSD9XwET9XJ3srGEFXP6AfHhAka
clientSecret: zuPTcdJH435h3wgl055XNZ5ffNMa
scope: openid
clientAuthenticationScheme: header
resource:
userInfoUri: https://localhost:9443/oauth2/userinfo?schema=openid
In terms of my own investigative efforts, of concern is that in the DefaultOAuthClientContext preserved state gets cleared right before it needs to used, this appears to be a sequencing issue.
- DefaultAccessTokenRequest.setPreservedState(http://localhost:9998/login)
- DefaultOAuth2ClientContext.state.put(avjDRM,http://localhost:9998/login)
- DefaultAccessTokenRequest.setPreservedState(http://localhost:9998/login)
- DefaultOAuthClientContext.state.put(MREOgG,http://localhost:9998/login)
- LOGIN ON WSO2 FORM
- DefaultOAuth2ClientContext.state.remove(avjDRM)
- OAUth2RestTemplate…acquireAccessToken…...Object preservedState = oauth2Context.removePreservedState(avjDRM)
I'm using the latest releases of Spring Boot (1.3.0) and WSO2 Identity Server (5.0). Also using spring-security-oauth 2.0.8.