# How CoSec Integrates with Social Authentication Providers: OAuth/OIDC Implementation Guide

> Learn how CoSec integrates with social authentication providers like Google and GitHub using OAuth/OIDC. This guide details the JustAuth integration for a flexible login experience.

- Repository: [Ahoo Wang/cosec](https://github.com/ahoo-wang/cosec)
- Tags: how-to-guide
- Published: 2026-02-23

---

**CoSec provides a pluggable social authentication subsystem that delegates user login to external OAuth/OIDC providers like Google, GitHub, and WeChat through a provider-based architecture built on JustAuth integration.**

CoSec (Context-Oriented Security) is a high-performance authentication and authorization framework that natively supports social authentication integration. The `cosec-social` module provides a clean abstraction layer allowing you to integrate CoSec with social authentication providers without modifying core security logic, as implemented in the [ahoo-wang/cosec](https://github.com/ahoo-wang/cosec) repository.

## Core Architecture of CoSec Social Authentication

The social authentication system in CoSec is built on three foundational components that work together to manage OAuth flows.

### SocialAuthenticationProvider Interface

The **`SocialAuthenticationProvider`** interface defines the contract that every social provider must implement. Located in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialAuthenticationProvider.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialAuthenticationProvider.kt), it specifies two critical operations:

- `authorizeUrl()` – Generates the redirect URL to initiate the OAuth flow with the external provider
- `authenticate(credentials)` – Exchanges the authorization callback (code and state) for a `SocialUser` principal

### SocialProviderManager Registry

The **`SocialProviderManager`** acts as a thread-safe registry storing all available providers. Implemented in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialProviderManager.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialProviderManager.kt), it uses a `ConcurrentHashMap` to maintain provider instances by name and exposes `getRequired(name)` for lookup operations.

### SocialAuthentication Entry Point

The **`SocialAuthentication`** class serves as the high-level API that coordinates between the security framework and individual providers. Defined in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialAuthentication.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/SocialAuthentication.kt), it forwards `authorizeUrl(provider)` and `authenticate(credentials)` calls to the appropriate provider resolved from the `SocialProviderManager`.

## JustAuth Integration for OAuth Providers

CoSec ships with a concrete implementation based on the **JustAuth** library, which supports dozens of OAuth providers out of the box.

### JustAuthProvider Implementation

The `JustAuthProvider` class in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/JustAuthProvider.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/JustAuthProvider.kt) wraps JustAuth's `AuthRequest` objects. It implements the `SocialAuthenticationProvider` interface by:

1. Creating an `AuthRequest` (JustAuth's wrapper around OAuth endpoints) during initialization
2. Delegating `authorizeUrl()` calls to the underlying `AuthRequest`
3. Handling token exchange and user info retrieval in `authenticate()`

### SocialUser Conversion

The `SocialUserConverter` in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/SocialUserConverter.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/SocialUserConverter.kt) maps JustAuth's `AuthUser` objects to CoSec's internal `SocialUser` model, ensuring consistent principal representation regardless of the external provider.

## Spring Boot Auto-Configuration

When using the **`cosec-spring-boot-starter`**, social authentication requires zero code changes to configure standard providers.

### CoSecSocialAuthenticationAutoConfiguration

The `CoSecSocialAuthenticationAutoConfiguration` bean in [`cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authentication/social/CoSecSocialAuthenticationAutoConfiguration.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-spring-boot-starter/src/main/kotlin/me/ahoo/cosec/spring/boot/starter/authentication/social/CoSecSocialAuthenticationAutoConfiguration.kt) handles automatic provider registration:

1. Reads `SocialAuthenticationProperties` from [`application.yml`](https://github.com/ahoo-wang/cosec/blob/main/application.yml) under the `cosec.authentication.social` prefix
2. For each registration entry, instantiates the corresponding JustAuth `AuthRequest` via reflection
3. Wraps each request in a `JustAuthProvider` and registers it with `SocialProviderManager`

### YAML Configuration Example

Configure providers in [`application.yml`](https://github.com/ahoo-wang/cosec/blob/main/application.yml) to enable social authentication:

```yaml
cosec:
  authentication:
    social:
      enabled: true
      registration:
        google:
          type: com.xkcoding.oauth2.client.GoogleAuthRequest
          clientId: ${GOOGLE_CLIENT_ID}
          clientSecret: ${GOOGLE_CLIENT_SECRET}
          redirectUri: https://myapp.com/auth/social/google/callback
        github:
          type: com.xkcoding.oauth2.client.GithubAuthRequest
          clientId: ${GITHUB_CLIENT_ID}
          clientSecret: ${GITHUB_CLIENT_SECRET}
          redirectUri: https://myapp.com/auth/social/github/callback

```

The auto-configuration reads this map and registers providers automatically, making **adding new social providers a configuration-only task**.

## Implementing Social Login in Controllers

Use the `SocialAuthentication` bean in your Spring MVC controllers to handle OAuth flows:

```kotlin
@RestController
@RequestMapping("/auth/social")
class SocialAuthController(
    private val socialAuthentication: SocialAuthentication
) {
    
    // Redirect user to provider's authorization endpoint
    @GetMapping("/{provider}")
    fun redirect(@PathVariable provider: String): ResponseEntity<Void> {
        val url = socialAuthentication.authorizeUrl(provider)
        return ResponseEntity.status(HttpStatus.FOUND)
            .location(URI.create(url))
            .build()
    }

    // Handle OAuth callback from provider
    @GetMapping("/{provider}/callback")
    fun callback(
        @PathVariable provider: String,
        @RequestParam code: String,
        @RequestParam state: String
    ): Mono<ResponseEntity<String>> {
        val credentials = JustAuthCredentials(provider, code, state)
        return socialAuthentication.authenticate(credentials)
            .map { principal -> ResponseEntity.ok("Welcome ${principal.id}") }
    }
}

```

The `JustAuthCredentials` class in [`cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/JustAuthCredentials.kt`](https://github.com/ahoo-wang/cosec/blob/main/cosec-social/src/main/kotlin/me/ahoo/cosec/social/justauth/JustAuthCredentials.kt) carries the provider name, authorization code, and state parameter required for token exchange.

## Extending with Custom Providers

For providers not covered by JustAuth, implement the `SocialAuthenticationProvider` interface directly.

### Custom Provider Implementation

```kotlin
class MyOidcProvider(
    override val name: String,
    private val clientId: String,
    private val clientSecret: String,
    private val tokenEndpoint: String,
    private val userInfoEndpoint: String
) : SocialAuthenticationProvider {

    override fun authorizeUrl(): String =
        "https://example.com/oauth/authorize?client_id=$clientId&response_type=code&redirect_uri=$redirectUri"

    override fun authenticate(credentials: SocialCredentials): Mono<SocialUser> {
        // Exchange code for token, call userInfoEndpoint, map to SocialUser
        // Implementation details omitted for brevity
        return Mono.just(SocialUser(id = "user123", attributes = emptyMap()))
    }
}

```

### Manual Registration

Register custom providers manually in a Spring configuration class:

```kotlin
@Configuration
class CustomSocialConfig {
    @Bean
    fun customSocialProvider(): SocialAuthenticationProvider {
        val provider = MyOidcProvider(
            name = "customOidc",
            clientId = "abc",
            clientSecret = "def",
            tokenEndpoint = "https://example.com/oauth/token",
            userInfoEndpoint = "https://example.com/oauth/userinfo"
        )
        SocialProviderManager.register(provider)
        return provider
    }
}

```

## Summary

- **CoSec integrates with social authentication providers** through a three-layer architecture: `SocialAuthenticationProvider` defines the contract, `SocialProviderManager` handles registration, and `SocialAuthentication` provides the API.
- **JustAuth integration** in `cosec-social` enables immediate support for Google, GitHub, WeChat, and other major OAuth providers without custom code.
- **Spring Boot auto-configuration** reads `cosec.authentication.social` properties from [`application.yml`](https://github.com/ahoo-wang/cosec/blob/main/application.yml) and automatically registers providers, supporting configuration-only setup.
- **Custom provider support** allows you to implement `SocialAuthenticationProvider` directly and register it via `SocialProviderManager.register()` for non-standard OAuth implementations.

## Frequently Asked Questions

### How do I add a new social provider in CoSec?

Add the provider configuration to [`application.yml`](https://github.com/ahoo-wang/cosec/blob/main/application.yml) under `cosec.authentication.social.registration` with the appropriate `type` (JustAuth request class), `clientId`, `clientSecret`, and `redirectUri`. The `CoSecSocialAuthenticationAutoConfiguration` will automatically instantiate and register the provider at startup.

### Can I use CoSec social authentication without Spring Boot?

Yes. You can manually instantiate `JustAuthProvider` or custom implementations of `SocialAuthenticationProvider` and register them using `SocialProviderManager.register(provider)`. This approach works in any Kotlin/Java application, though you must handle the OAuth callback routing yourself.

### What OAuth providers are supported by CoSec out of the box?

CoSec supports all providers available in the JustAuth library, including Google, GitHub, GitLab, Microsoft, WeChat, QQ, Weibo, and dozens of others. The specific provider is determined by the `type` field in your YAML configuration, which must reference a valid JustAuth `AuthRequest` implementation class.

### How does CoSec handle the OAuth callback and token exchange?

The `SocialAuthentication.authenticate(credentials)` method delegates to the registered provider's `authenticate` implementation. For JustAuth-based providers, this uses the `JustAuthProvider` class to exchange the authorization code for an access token, retrieve user information, and convert the result to a `SocialUser` via `SocialUserConverter`, all within a reactive `Mono` stream.