Firstly, to prepare for a Single Sign-On (SSO) solution using OAuth 2.0 with OpenID
Connect. Done.
Next is to establish an Authorization Server
or Identity Provider (IdP)
. Done.
Then, I need to register the ReactJS application with the authentication server.
I revamped the client registration page to cater specifically to our use case, involving one client for the SpringBoot resource server, one for the ReactJS frontend, and one for the iOS mobile end. The registration process now follows a template-style approach. All that’s required is to select the desired app, provide the home URL, choose a template, and the remaining settings will be automatically populated.
Upon completion, I obtain the client-id
and redirect_uri
. ReactJs is using the Authorization Code Grant with Proof Key for Code Exchange (PKCE)
. I’ll now provide a brief demonstration of these two flows.
Authorization Code Grant
- 1. Authorization Request (
/oauth2/authorize
):- 1.1 User authenticates and grants permission.
- 1.2 Redirect the user to the authorization endpoint.
Parameter | Value | Required |
---|---|---|
response_type | code | Required |
client_id | Required | |
redirect_uri | http://localhost:3000/authorized | Required |
scope | openid profile | Required |
state | optional |
- 2. Authorization Response:
- The authorization server redirects back to the client with an authorization code
https://cowpte.com:8702/authorized?code=***&state=***
- The authorization server redirects back to the client with an authorization code
- 3. Token Request (
/oauth2/token
):- The client exchanges the authorization code for an access token.
Parameter | Value | Description |
---|---|---|
grant_type | authorization_code | |
code | ||
client_id | ||
client_secret | to verify the client | |
redirect_uri | exact same as for /oauth2/authorize, for extra security |
- 4. Token Response
- The authorization server responds with the
Access Token
.
- The authorization server responds with the
{
"access_token": "...",
"scope": "openid profile",
"id_token": "...",
"token_type": "Bearer",
"expires_in": 299
}
- 5. API calling
PKCE
PKCE (Proof Key for Code Exchange) is an extension for the Authorization Code Grant flow. It enhances security by replacing the need for a client_secret
with a code_hallenge
and code_verifier
. This is particularly for public clients where storing a client secret in a browser is considered unsafe.
The parameters for /oauth2/authorize
and /oauth2/token
have been adjusted as follows:
Parameter | Value | Required |
---|---|---|
response_type | code | Required |
client_id | Required | |
redirect_uri | http://localhost:3000/authorized | Required |
scope | openid profile | Required |
state | Optional. A random value generated by your client, which will be included in the response to help prevent cross-site request forgery (CSRF) attacks | |
code_challenge | Required | |
code_challenge_method | S256 | Required |
Parameter | Value | Description |
---|---|---|
grant_type | authorization_code | |
code | your_authorization_code | |
client_id | ||
code_verifier | to verify the client | |
redirect_uri | exact same as for /oauth2/authorize, for extra security |
SpringBoot CORS
Configure CORS in Spring Boot by adding the following snippet to WebSecurityConfig.java.
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class WebSecurityConfig {
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
config.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
I initially set config.setAllowedOrigins(Arrays.asList("*"))
, but it didn’t work. It started functioning only when explicitly set to config.setAllowedOrigins(Arrays.asList("http://localhost:3000"))
.
For more insights, refer to this helpful documentation: https://docs.spring.io/spring-authorization-server/reference/guides/how-to-pkce.html
To gain a deeper understanding of OAuth2.0 flows, especially Authorization Code Grant or PKCE, you can explore: https://www.oauth.com/playground/index.html
To access our server’s authorization and token endpoints, visit https://cowpte.com:8702/.well-known/openid-configuration.
Next, set up the ReactJs npm package. Various Identity Providers (IdP) offer their own packages, such as auth0. I have successfully tested the asgardeo package.
Additionally, the react-oauth2-pkce package is compatible with our IdP.
npm package | IdP | Sample |
---|---|---|
@auth0/auth0-react | auth0 | No |
https://github.com/asgardeo/asgardeo-auth-react-sdk | asgardeo | Yes |
https://github.com/soofstad/react-oauth2-pkce | IdP agnostic | Yes |
The experiment to establish a connection between ReactJs and the SpringBoot authorization server for Single Sign-On has been successfully concluded.
The next phase involves integrating this functionality into our Frontend project. This may entail transitioning from JavaScript to TypeScript, given that the react-oauth2-pkce package is TypeScript-based. Additionally, there is a need to enhance the logic for user registration and password recovery in the Authorization Server.