Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure AD and Spring Security with Oauth 2

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.

like image 934
Cristian Sandu Avatar asked Oct 18 '22 04:10

Cristian Sandu


1 Answers

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.

like image 57
Nergal Avatar answered Oct 20 '22 23:10

Nergal