# Bella OpenAPI OAuth 2.0 and CAS Integration: Complete SSO Implementation Guide

> Implement OAuth 2.0 and CAS single sign-on with Bella OpenAPI. This guide details Spring Boot filter integration validating tickets and mapping user attributes for secure SSO.

- Repository: [Ke Technologies/bella-openapi](https://github.com/lianjiatech/bella-openapi)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Bella OpenAPI activates OAuth 2.0 or CAS single sign-on through conditional Spring Boot filters that validate tickets, map user attributes to an `Operator` object, and persist sessions via a pluggable `SessionManager`.**

Bella OpenAPI (lianjiatech/bella-openapi) provides enterprise-grade single sign-on by implementing two distinct authentication protocols as configurable Spring Boot modules. Whether you need social login via OAuth 2.0 providers like Google and GitHub or enterprise CAS server integration, the system uses servlet filters and conditional bean registration to handle the complete authentication lifecycle without code changes. Both mechanisms share a common session architecture that stores the authenticated `Operator` in Redis or HTTP sessions.

## OAuth 2.0 Implementation Architecture

The OAuth 2.0 stack activates automatically when you set `bella.login.type=oauth` and define `bella.login.login-page-url` in your configuration. This triggers the `@ConditionalOnOAuthEnable` annotation, which registers the `OAuthLoginFilter` through `BellaLoginConfiguration.oauthLoginFilter` (lines 71-81).

### Activation and Configuration

The `OAuthProperties` bean holds provider-specific credentials and redirect URIs. When the application context loads, `BellaLoginConfiguration` instantiates the `OAuthLoginFilter` and assigns it high precedence in the servlet filter chain.

```yaml
bella:
  login:
    type: oauth
    login-page-url: /login
  oauth:
    providers:
      google:
        client-id: YOUR_GOOGLE_ID
        client-secret: YOUR_GOOGLE_SECRET
        redirect-uri: https://myapp.com/openapi/oauth/callback/google

```

### Authentication Flow

The implementation follows a standard authorization code flow with CSRF protection:

1. **Discovery endpoint**: Clients call `/openapi/oauth/config?redirect=...`. The `OAuthLoginFilter.handleOAuthConfig` method (lines 68-84) returns a JSON array containing the **authorization URL** for each enabled provider.
2. **State generation**: The `TicketManager` generates a secure ticket stored in the `state` parameter to prevent CSRF attacks.
3. **Provider redirect**: The user agent navigates to the provider's authorization endpoint.
4. **Callback handling**: Upon return to `/openapi/oauth/callback/{provider}`, `OAuthLoginFilter.handleCallback` (lines 92-128) validates the state ticket, exchanges the code for an access token via the concrete `OAuthService` implementation, and fetches user information.
5. **Session creation**: The filter creates an `Operator` instance and calls `sessionManager.create(operator, request, response)` to persist the authentication.

### Core OAuth Components

- **`OAuthLoginFilter`**: Orchestrates the config endpoint, callback processing, and ticket validation.
- **`OAuthService` interface**: Defines the contract for provider-specific logic including URL construction and user info retrieval.
- **`GoogleOAuthService` / `GithubOAuthService`**: Concrete implementations that format provider requests and parse responses.
- **`ConditionalOnOAuthEnable`**: Spring condition that activates the OAuth bean stack only when required properties are present.

## CAS (Central Authentication Service) Integration

Bella OpenAPI implements enterprise CAS integration through a three-filter chain that handles redirection, ticket validation, and post-login forwarding. Activation requires `bella.login.type=cas` and `bella.cas.server-url-prefix`.

### Filter Chain Configuration

When `@ConditionalOnCasEnable` matches, `BellaLoginConfiguration` (lines 47-69) creates three filters via `BellaCasClient`:

- **`BellaCasLoginFilter`**: Detects unauthenticated console requests and redirects to the CAS server.
- **`BellaValidatorFilter`**: Extends `Cas30ProxyReceivingTicketValidationFilter` to validate service tickets and extract user attributes.
- **`BellaRedirectFilter`**: Handles the final redirect to the originally requested resource.

### Login and Validation Flow

The CAS flow begins when a request includes the `X-Console-Login` header:

1. **Redirect generation**: `BellaCasLoginFilter.doFilter` (lines 64-79) constructs a service URL pointing back to the application and redirects the browser to `CasProperties.serverLoginUrl`.
2. **Ticket validation**: After authentication at the CAS server, the user returns with a `ticket` parameter. `BellaValidatorFilter` validates this against the CAS server and maps attributes (ucid, displayName, email) to an `Operator` in `onSuccessfulValidation` (lines 37-55).
3. **Attribute mapping**: The filter reads attribute names from `CasProperties` (id-attribute, name-attribute, email-attribute) to populate the `Operator`.
4. **Post-login routing**: If the original request contained a `redirect` parameter, `BellaValidatorFilter` stores it for `BellaRedirectFilter` to complete the navigation (lines 56-58).

```yaml
bella:
  login:
    type: cas
  cas:
    server-url-prefix: https://cas.mycompany.com/cas
    server-login-url: https://cas.mycompany.com/cas/login
    client-host: https://myapp.com
    id-attribute: ucid
    name-attribute: displayName
    email-attribute: email

```

### Key CAS Components

- **`BellaCasLoginFilter`**: Initiates the CAS protocol by building the service URL and redirecting unauthenticated users.
- **`BellaValidatorFilter`**: Bridges the CAS client library with Bella's `SessionManager` by converting successful validations into persisted sessions.
- **`CasProperties`**: Type-safe configuration holder for server URLs and attribute mappings.
- **`ConditionalOnCasEnable`**: Ensures CAS beans load only when explicitly configured.

## Shared Session Management

Both OAuth and CAS implementations delegate session persistence to the `SessionManager` interface defined in `BellaLoginConfiguration.sessionManager` (lines 90-115). The system selects an implementation based on your deployment profile:

- **`RedisSessionManager`**: Production-ready distributed session storage.
- **`HttpSessionManager`**: Cookie-based sessions for single-node deployments.

After successful authentication, the `Operator` object remains available for the duration of the session. The generic `LoginFilter` intercepts all subsequent requests, retrieves the `Operator` from the session, and injects it as a request attribute for downstream controllers.

## Practical Configuration Examples

### Enabling Google and GitHub OAuth

Configure multiple providers simultaneously by listing them under `bella.oauth.providers`:

```yaml
bella:
  login:
    type: oauth
    login-page-url: /login
  oauth:
    providers:
      google:
        client-id: ${GOOGLE_CLIENT_ID}
        client-secret: ${GOOGLE_CLIENT_SECRET}
        redirect-uri: https://api.example.com/openapi/oauth/callback/google
      github:
        client-id: ${GITHUB_CLIENT_ID}
        client-secret: ${GITHUB_CLIENT_SECRET}
        redirect-uri: https://api.example.com/openapi/oauth/callback/github

```

**Frontend integration** – Fetch available providers and redirect the user:

```javascript
async function initiateLogin(returnUrl) {
  const response = await fetch(`/openapi/oauth/config?redirect=${encodeURIComponent(returnUrl)}`);
  const { data: providers } = await response.json();
  
  // providers = [{type: 'google', authUrl: 'https://accounts.google.com/...'}]
  const google = providers.find(p => p.type === 'google');
  if (google) window.location.href = google.authUrl;
}

```

### Configuring Enterprise CAS

Trigger CAS authentication by including the special header when accessing protected console resources:

```html
<script>
  fetch('/console', {
    headers: { 'X-Console-Login': 'true' },
    redirect: 'follow'
  }).then(response => {
    if (response.redirected) {
      window.location.href = response.url; // Redirects to CAS server
    }
  });
</script>

```

### Accessing the Authenticated Operator

Retrieve the current user in your Spring controllers by casting the request attribute set by `LoginFilter`:

```java
@RestController
@RequestMapping("/api/user")
public class UserController {

    @GetMapping("/profile")
    public Operator getProfile(HttpServletRequest request) {
        return (Operator) request.getAttribute("operator");
    }
}

```

## Summary

- **OAuth 2.0** activates via `@ConditionalOnOAuthEnable` when `bella.login.type=oauth` is set, using `OAuthLoginFilter` to handle the authorization code flow and provider callbacks.
- **CAS** activates via `@ConditionalOnCasEnable` when `bella.login.type=cas` is set, employing three specialized filters (`BellaCasLoginFilter`, `BellaValidatorFilter`, `BellaRedirectFilter`) to manage the ticket validation dance.
- Both mechanisms store the resulting `Operator` object through the shared `SessionManager` interface, supporting both Redis-backed and HTTP session storage.
- Configuration is purely property-driven, allowing you to switch between OAuth, CAS, or client-mode authentication without modifying source code or rebuilding the application.

## Frequently Asked Questions

### How do I switch between OAuth and CAS in Bella OpenAPI?

Change the value of `bella.login.type` to `oauth` or `cas` in your [`application.yml`](https://github.com/lianjiatech/bella-openapi/blob/main/application.yml). Ensure you include the required companion properties (`bella.login.login-page-url` for OAuth, `bella.cas.server-url-prefix` for CAS) to satisfy the conditional activation annotations.

### What triggers the CAS login flow in Bella OpenAPI?

The `BellaCasLoginFilter` specifically checks for the `X-Console-Login: true` header on incoming requests. When this header is present and the user lacks a valid session, the filter redirects the browser to the configured CAS server login URL.

### How does Bella OpenAPI prevent CSRF attacks during OAuth authentication?

The `OAuthLoginFilter` generates a cryptographically secure ticket through the `TicketManager` and embeds it in the `state` parameter of the authorization URL. When the provider redirects back to `/openapi/oauth/callback/{provider}`, the filter validates that the returned state matches the stored ticket before processing the authorization code.

### Where does Bella OpenAPI store authenticated user sessions?

Both OAuth and CAS implementations call `sessionManager.create(operator, request, response)` upon successful authentication. Depending on your configuration, this persists the `Operator` object to either **Redis** (via `RedisSessionManager`) or **HTTP sessions** (via `HttpSessionManager`). Subsequent requests retrieve this object via the generic `LoginFilter` and expose it as a request attribute named `"operator"`.