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

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 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, 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, 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, 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 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 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 handles automatic provider registration:

  1. Reads SocialAuthenticationProperties from 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 to enable social authentication:

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:

@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 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

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:

@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 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 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.

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 →