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

> Integrate third-party login using OAuth with JustAuth in ContiNew Admin for secure, automated authentication and user provisioning. Get started now!

- Repository: [OpenContiNew/continew-admin](https://github.com/continew-org/continew-admin)
- Tags: how-to-guide
- Published: 2026-02-28

---

**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`](https://github.com/continew-org/continew-admin/blob/main/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`](https://github.com/continew-org/continew-admin/blob/main/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`](https://github.com/continew-org/continew-admin/blob/main/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:

```java
// 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:

```javascript
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`](https://github.com/continew-org/continew-admin/blob/main/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`](https://github.com/continew-org/continew-admin/blob/main/application.yml) or [`application-dev.yml`](https://github.com/continew-org/continew-admin/blob/main/application-dev.yml) under the `justauth` namespace:

```yaml
justauth:
  type:
    github:
      client-id: your-client-id
      client-secret: your-client-secret
      redirect-uri: http://localhost:8080/oauth/callback/github

```

3. **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

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

```

### Handling the Callback and Completing Login

```javascript
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`](https://github.com/continew-org/continew-admin/blob/main/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`](https://github.com/continew-org/continew-admin/blob/main/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`](https://github.com/continew-org/continew-admin/blob/main/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.