We are trying to implement a SSO scheme using Azure AD and Spring security. We found a few leads:
https://github.com/spring-guides/tut-spring-boot-oauth2
https://github.com/Pytry/azure-b2c-oauth2
But none of these tell the full story. In fact we can't get passed the access token parsing, Spring has a different idea of what the JWT token should be.
Ideally we wouldn't want to write an SSO filter from scratch but override the Token Services to implement custom filtering for starters.
Has anyone successfully implemented this? Any help would be appreciated.
Update: I found an easier method. Just add a resource parameter after the userAuthorizationUri
.
security:
oauth2:
client:
...
userAuthorizationUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/authorize?resource=https://graph.windows.net
...
https://stackoverflow.com/a/45828135/2231168
Original answer
At my office we found a foreign blog post which lead us to the final implementation http://statemachine.hatenablog.com/entry/2016/04/19/155920
As a workaround, you had to add two classes to capture OAuth2RestTemplate and request enhancers. It works with spring boot 1.3.8 which contains spring 4.2.8, we couldn't make it work with higher version.
application.yml:
azure:
resource: https://graph.windows.net
security:
oauth2:
client:
clientId: <<your client id>>
clientSecret: <<your client secret>>
accessTokenUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/token
userAuthorizationUri: https://login.microsoftonline.com/<<tenantId>>/oauth2/authorize
clientAuthenticationScheme: form
scope: openid
resource:
userInfoUri: https://graph.windows.net/me?api-version=1.6
AzureRequestEnhancer:
@Component
public class AzureRequestEnhancer implements RequestEnhancer {
@Value("${azure.resource:null}")
private String aadResource;
@Override
public void enhance(AccessTokenRequest request, OAuth2ProtectedResourceDetails resource, MultiValueMap<String, String> form, HttpHeaders headers) {
if (!StringUtils.isEmpty(resource)) {
form.set("resource", aadResource);
}
}
}
AzureRequestEnhancerCustomizer:
@Component
public class AzureRequestEnhancerCustomizer {
@Autowired
private OAuth2RestTemplate userInfoRestTemplate;
@Autowired
private AzureRequestEnhancer azureRequestEnhancer;
@PostConstruct
public void testWiring() {
AuthorizationCodeAccessTokenProvider authorizationCodeAccessTokenProvider = new AuthorizationCodeAccessTokenProvider();
authorizationCodeAccessTokenProvider.setTokenRequestEnhancer(azureRequestEnhancer);
userInfoRestTemplate.setAccessTokenProvider(authorizationCodeAccessTokenProvider);
}
}
The PostConstruct
annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.
I hope this helps you with the implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With