A minimal Spring Boot 2.0 project demonstrating how to integrate Azure AD with the new Spring Security 5 + OAuth 2 login features.
Because Spring Security recently moved some of the functionality from the previously recommended spring-security-oauth
package into core, and will replace it entirely over time. See this compatibility matrix for details. Many examples on the web are no longer compatible with Spring Boot 2.0 / Spring Security 5.0 after this breaking change.
- Edit
src/main/resources/application.yaml
and plug in your Azure AD application's client ID and secret. The app needs to be registered in Azure AD with at least the "Sign-in and read user profile" permission (i.e. User.Read scope) against Microsoft Graph (not the default Windows Azure AD Graph API that is added for new apps). - Run
mvn spring-boot:run
to start the local webserver. - Open one of the endpoints below in your browser of choice
http://localhost:8080/hello/foo
: echoesfoo
back at you (for your choice offoo
)http://localhost:8080/oauth2/authorization/microsoft
: attempts to login the user using the OAuth2 code grant against AAD, followed by a Graph call to obtain user informationhttp://localhost:8080/claims
: Displays info on the currently logged in user
Note that because no homepage is configured, after login you'll get a 404 error when hitting http://localhost:8080
. This is expected; hit the /claims
endpoint to verify that your session has the claims stored.
I found these resources helpful while troubleshooting:
- Spring Security's OAuth2 feature matrix
- Spring Security 5 OAuth 2.0 Login Sample (Okta)
- Spring Security 5 -- OAuth2 Login by Loredana Crusoveanu
- Overriding Spring Boot 2.0 Auto-configuration from Spring docs
- (Deprecated) Spring Boot and OAuth2 tutorial
- Spring Boot's OAuth2 Client from Spring docs
- 'cannot be null' errors in Spring Security 5
A lesson learned: searching specifically for Spring Security 5's OAuth2 implementation is near impossible since you always end up getting results for the older "Spring Security OAuth" 2.x implementation, even if you put a time restriction on results such as "within last year".
Based on lots of trial and error, I would caution that you are not reading about the new Spring Security 5's OAuth2 implementation if you see:
@EnableOAuth2Sso
in the code sample- The properties/YAML configuration start directly with
security
(instead ofspring
followed bysecurity
, which indicates for Spring Security 5) - The properties/YAML configuration in camelCase (new config in Spring Security 5 is snake-case)
- A dependency on the
spring-security-oauth2
package inpom.xml
(butspring-security-oauth2-client
orspring-security-oauth2-jose
would be OK for Spring Security 5)
Disclaimer: I am not a Spring framework expert, this is my best guess from limited experience with it
Java 8 (and possibly later) default to an invalid Accept header value of text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
which upsets many API endpoints, including Microsoft Graph (besides the point that a REST endpoint is not going to be able to spit back user info in HTML/GIF/JPEG format to Java).
As a result, two classes from Spring needed to be customized (e.g. copied and lightly modified) in order to ensure the appropriate Accept header was used. You will find these two classes in the replacements
sub-package.