Validate Azure token in a Spring boot application - spring-boot

I have an application with a React FrontEnd and a spring boot backend. Here is my problem: I have to autorize my frontend in my back with my microsoft token. From here I manage to :
From my front page when I click on my login button it redirect me to
azure connection portal (I used msal.js library)
After the redirection, I have an access token.
Now, I want to send this access token to my back (something like /api/auth), call the microsoft graph api to retrieve users informations, create the user in my DataBase if he doesn't exists and then return information with a token that will allow my front to be authorized when it requests protected endpoints

Please use these samples for your reference. Mostly we will use either of the ADD resource server approach.
Hope you have the necessary dependencies in your application(azure-core, azure-spring-boot-starter-active-directory, spring-boot-starter-oauth2-client, spring-boot-starter-oauth2-resource-server and the normal spring web dependency).
The JWT token which you recived through frontend can be attached as a barer token with each request you are making to the spring boot app.
Include the below class for validating the azure JWT token.
import com.azure.spring.aad.webapi.AADJwtBearerTokenAuthenticationConverter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests((requests) -> requests.anyRequest().authenticated())
.oauth2ResourceServer()
.jwt()
.jwtAuthenticationConverter(new AADJwtBearerTokenAuthenticationConverter());
}
}
In case you come acorss with corss issue please add a filter to attach corss orgin in header.
Hope it will help.

Spring Security can be used to validate the token, you can take a look at this sample.

Related

Can I configure the Keycloak Spring Boot adapter so that it populates the user principal even on requests that don't require authorization?

If I have an endpoint which should be publically available but behave differently if you're logged in, I can't specify it in the security-constraints section of my application configuration (otherwise if I'm not logged in I can't reach the endpoint at all). But without it being listed there, the user principal never gets populated on the request, even if a valid Bearer token is provided in the Authorization header.
Is there a way to get the behaviour I want with the basic Spring Boot adapter? If not, am I likely to have more luck with the Spring Security adapter?
A solution to this is to enable preemptive authentication in the Tomcat context. Assuming you're deploying using the embedded server, you can implement a WebServerFactoryCustomizer as follows:
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;
#Component
public class PreemptiveAuthWebServerCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>
{
#Override
public void customize( final TomcatServletWebServerFactory factory )
{
factory.addContextCustomizers( context -> context.setPreemptiveAuthentication( true ) );
}
}
Now if a request has an Authorization header sent, it will always be processed even if the request isn't explicitly behind a path which requires authorization.

Mobile app authentication for existing API

I have application with Spring security. It's REST api for Angular SPA. It uses session and cookie mechanism. Now I want to access this api from mobile application (Nativescript). I spent some time searching for best way to authenticate mobile app user. In the most cases oauth2 and jwt tokens are advised. So I've done reasearch on this and decided to add additional (seperate) authentication only for mobile application. So Angular app still will be using session with path api/... and mobile app will be using token mechanism with path /api/mobile/... (underneath it will be the same api but with different prefix).
I've decided to use OAuth2 and its Spring integration. I've read documentation and I'm consfused. Why they always mention about authentication provider (Google, Github, Facebook)? I don't want to force my users to login via other service. I want to allow them login with credentials they already registered with in my application. How this social login even related with oAuth authorization server? All examples they've provided use some other services.
I've also tried to add my authorization server in my existing app. I've successfully retrieved token. But now I don't understand all this relationships. There is authorization server that keeps client id and client server. But why /auth/token endpoint needs another authentication? So mobile app needs to provide 3 different credentials - user credentials, client id and secret and token endpoint credentials.
Did I miss something? I know that OAuth is only specification and Spring is implementation of it. But I'm under impression that Spring overcomplicates this. And do I need oauth at all since I have only 1 type of resource?
#Configuration
#EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(clientId)
.secret(passwordEncoder.encode(clientSecret))
.authorizedGrantTypes("refresh_token", "authorization_code", "password", "implicit")
.scopes(scopeRead, scopeWrite)
.resourceIds(resourceIds);
}
}

Azure Active Directory with Springboot : how to handle expired oauth token?

I have a springboot app which use Microsoft Azure active directory to allow authentication (oauth2).
I have followed the "how to" provided by Microsoft (https://learn.microsoft.com/en-us/java/azure/spring-framework/configure-spring-boot-starter-java-app-with-azure-active-directory?view=azure-java-stable).
Everything is working well except that I have no ideas on how to handle expired token (after 1 hour) in a way that it will not affect the users.
I know that it is possible to get new token with the refresh token but if I take a look in NimbusAuthorizationCodeTokenResponseClient.java the refresh token is not saved anywhere even if it's available.
I don't find any examples on how to keep this refresh token and how to use it, like if it was supposed to work automatically like the whole process.
Can someone have any experience with this Azure Active directory spring boot module?
I'm using Springboot 2.0.4 with azure spring boot module 2.0.5
Your access_token gets automatically refreshed by the refresh_token.
But when your refresh_token token expires you can still run into the same error. To handle it you can make your refresh_token automatically renew the same time you get a new access_token. Use reuseRefreshTokens(false) in the configuration of AuthorizationServerEndpointsConfigurer at the auth-server code:
Take a look at the refreshAccessToken method in the DefaultTokenServices class:
public OAuth2AccessToken refreshAccessToken(String refreshTokenValue,
TokenRequest tokenRequest) {
// Omitted
if (!reuseRefreshToken) {
tokenStore.removeRefreshToken(refreshToken);
refreshToken = createRefreshToken(authentication);
}
// Omitted
}
You should somehow set the reuseRefreshToken flag to false. You can do that in your AuthorizationServerConfigurerAdapter implementation:
#Configuration
#EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
// Other methods
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.reuseRefreshTokens(false);
}
}

Angular ts (front-end) + spring boot (back-end) OAuth2 flow

I want to implement authorization via Google and Microsoft in my full stack app (Angular 6 for front-end, Spring boot for back-end) and I've got a problem.
I follow this scheme which describes how the flow should be implemented:
OAuth2 Authorization Flow:
The problem is with Step 4 where front-end should send authorization code to back-end. I just don't know which endpoint to use and how to configure it in Spring Security configuration.
This endpoint should get authorization code, check it on OAuth provider side, request access and refresh token and remember the authorized user.
Maybe there is an example of how it should be done? Google answers do not seem appropriate.
What I already did:
Added #EnableOAuth2Sso annotation to the security configuration. But this is not what I actually need, because it enables authorization on back-end side. (redirecting to Google page works from back-end, but I need from front-end)
#EnableOAuth2Sso
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
Tried configuring Oauth2Login by myself.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated()
.and()
.oauth2Login()
.clientRegistrationRepository(clientRegistrationRepository)
.authorizedClientService(new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository));
}
Gradle dependencies:
<pre>
compile 'org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.0.RELEASE'
compile 'org.springframework.security:spring-security-oauth2-jose'
compile 'org.springframework.security:spring-security-oauth2-client'
</pre>
What I expect:
Some endpoint on back-end side, which accepts authorization code. For example:
URL: localhost:8080/oauth2/authcode/google
<pre>
{
"authorization_code": "...."
}
</pre>
And returns access token:
<pre>
{
"access_token": "...",
"expires": "..."
}
</pre>
And what is happening in the middle: back-end exchanges authorization code to access token and refresh token and saves it to own DB.
Thank you!

Stormpath: ERR_TOO_MANY_REDIRECTS

I'm using Stormpath for authentication in my website (developed with Spring Boot), but sometimes I receive ERR_TOO_MANY_REDIRECTS error. This happens every time I do the following:
1) Login to the website
2) Logout
3) Go to create a new user
4) Type the new user information
5) Click on create
The user is created, but the browser gives me ERR_TOO_MANY_REDIRECTS, and doesn't open anything. The only way to make it work again, is to clean the cookies and login again.
I'm using Spring Boot, so here's my configuration:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import static com.stormpath.spring.config.StormpathWebSecurityConfigurer.stormpath;
#Configuration
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.apply(stormpath());
}
}
Any idea why this is happening?
Thank you!
Never mind. The problem was with my stormpath version. I've updated it, and it's working great now. I was using an old version (1.0 RC6).

Resources