How to Integrate Third-Party Login (OAuth) with JustAuth in ContiNew Admin

ContiNew Admin provides a production-ready OAuth integration using the JustAuth library, enabling secure third-party authentication through generic endpoints and automated user provisioning.

ContiNew Admin simplifies social authentication by leveraging the JustAuth library to handle provider-specific protocols. The system abstracts OAuth complexity through a unified AuthRequestFactory and standardized handlers, allowing developers to add new providers via configuration rather than custom code. This guide explains the architecture, implementation steps, and configuration required to enable third-party login in the continew-org/continew-admin repository.

OAuth Architecture and Core Components

The OAuth implementation revolves around four primary components that handle authorization, callback processing, and account binding.

AuthRequestFactory

The AuthRequestFactory (provided by the continew-starter-auth-justauth module) creates pre-configured AuthRequest instances for any supported social source. This factory centralizes provider configuration and is imported across AuthController, SocialLoginHandler, and UserProfileController to ensure consistent OAuth behavior.

AuthController

Located in continew-system/src/main/java/top/continew/admin/auth/controller/AuthController.java, this controller exposes the /auth/{source} endpoint. The authorize() method generates third-party authorization URLs by calling authRequestFactory.getAuthRequest(source) and building the URL with authRequest.authorize(AuthStateUtils.createState()).

SocialLoginHandler

The SocialLoginHandler class in continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java manages the complete callback flow. Its login() method exchanges authorization codes for user information, creates local UserDO records for new users, generates UserSocialDO associations, and delegates to AbstractLoginHandler.authenticate() for JWT session creation.

UserProfileController

Found in continew-system/src/main/java/top/continew/admin/system/controller/UserProfileController.java, this controller enables authenticated users to bind additional social accounts. The bindSocial() method processes POST /user/profile/social/{source} requests to link new OAuth providers to existing profiles.

Implementing the OAuth Authentication Flow

The third-party login process follows a six-step sequence from initial request to session establishment.

Step 1: Request the Authorization URL

The front-end initiates login by calling GET /auth/{source} (e.g., /auth/gitee). The controller retrieves the appropriate AuthRequest from the factory and returns the authorization URL to the client:

// In AuthController.java (lines 88-93)
AuthRequest authRequest = authRequestFactory.getAuthRequest(source);
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
return R.ok("authorizeUrl", authorizeUrl);

The client redirects the user to this URL to authenticate with the third-party provider.

Step 2: Handle the Provider Callback

After user authentication, the provider redirects to the configured callback URL. The front-end extracts the code and state parameters and POSTs them to the social login endpoint:

const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');

fetch('/auth/social-login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ source: 'gitee', code, state })
});

Step 3: Process Login and Provision Users

The SocialLoginHandler.login() method (lines 81-98) processes the SocialLoginReq payload. It reconstructs the AuthRequest, calls authRequest.login(callback) to retrieve user info, and checks for existing social bindings. If unlinked, it creates a new UserDO with default roles and persists the UserSocialDO record.

Step 4: Establish the Session

Following successful authentication, AbstractLoginHandler.authenticate() generates a JWT (or Sa-Token) for the session. The front-end receives this token and stores it for subsequent authenticated API calls.

Step 5: Optional Social Account Binding

Logged-in users can bind additional providers by calling POST /user/profile/social/{source}. The UserProfileController.bindSocial() method validates the AuthCallback using the same AuthRequestFactory and stores the new association without creating duplicate user records.

Adding a New OAuth Provider

Extending support to additional OAuth providers requires only configuration and enum registration.

  1. Register the provider in continew-system/src/main/java/top/continew/admin/system/enums/SocialSourceEnum.java. Add the new source identifier (e.g., GITHUB, GOOGLE) to the enum.

  2. Configure credentials in application.yml or application-dev.yml under the justauth namespace:

justauth:
  type:
    github:
      client-id: your-client-id
      client-secret: your-client-secret
      redirect-uri: http://localhost:8080/oauth/callback/github
  1. Expose automatically: The generic /auth/{source} and /user/profile/social/{source} endpoints immediately recognize the new enum value without additional controller code.

Frontend Integration Examples

Requesting Authorization

fetch('/auth/gitee')
  .then(r => r.json())
  .then(resp => {
    window.location.href = resp.authorizeUrl;
  });

Handling the Callback and Completing Login

fetch('/auth/social-login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ 
    source: 'gitee', 
    code: authorizationCode, 
    state: returnedState 
  })
})
.then(r => r.json())
.then(loginResp => {
  localStorage.setItem('token', loginResp.data.token);
});

Summary

  • ContiNew Admin implements OAuth through the JustAuth library, providing a plug-and-play solution for third-party authentication.
  • The AuthRequestFactory centralizes provider configuration, while AuthController generates authorization URLs dynamically for any source defined in SocialSourceEnum.
  • SocialLoginHandler manages the complete callback lifecycle, including automatic user provisioning and JWT generation.
  • Account binding is handled by UserProfileController, allowing existing users to link multiple social identities.
  • New providers require only enum registration and YAML configuration, with no additional Java code needed thanks to the generic endpoint design.

Frequently Asked Questions

Which OAuth providers does ContiNew Admin support by default?

ContiNew Admin supports any provider compatible with the JustAuth library. The system uses SocialSourceEnum to define available sources, and you can add providers like Gitee, GitHub, Google, or enterprise OAuth by extending this enum and configuring the corresponding credentials in application.yml.

How does the system handle the OAuth callback securely?

The SocialLoginHandler.login() method in continew-system/src/main/java/top/continew/admin/auth/handler/SocialLoginHandler.java validates the callback by reconstructing the AuthRequest with the stored configuration and calling authRequest.login(callback). This verifies the state parameter and exchanges the code for an access token using the provider's API, ensuring the response originates from the legitimate OAuth service.

Can users bind multiple social accounts to one profile?

Yes. Authenticated users can bind additional third-party accounts through the POST /user/profile/social/{source} endpoint implemented in UserProfileController. The system creates a UserSocialDO record linking the new OAuth identity to the existing user without creating duplicate accounts, allowing login via any linked provider.

Where is the OAuth client configuration stored?

Client IDs, secrets, and redirect URIs are stored in application.yml (or environment-specific profiles) under the justauth namespace. The continew-starter-auth-justauth module automatically maps these properties to AuthConfig objects consumed by AuthRequestFactory, keeping credentials separate from source code.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →