Bella OpenAPI OAuth 2.0 and CAS Integration: Complete SSO Implementation Guide
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.
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:
- Discovery endpoint: Clients call
/openapi/oauth/config?redirect=.... TheOAuthLoginFilter.handleOAuthConfigmethod (lines 68-84) returns a JSON array containing the authorization URL for each enabled provider. - State generation: The
TicketManagergenerates a secure ticket stored in thestateparameter to prevent CSRF attacks. - Provider redirect: The user agent navigates to the provider's authorization endpoint.
- 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 concreteOAuthServiceimplementation, and fetches user information. - Session creation: The filter creates an
Operatorinstance and callssessionManager.create(operator, request, response)to persist the authentication.
Core OAuth Components
OAuthLoginFilter: Orchestrates the config endpoint, callback processing, and ticket validation.OAuthServiceinterface: 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: ExtendsCas30ProxyReceivingTicketValidationFilterto 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:
- Redirect generation:
BellaCasLoginFilter.doFilter(lines 64-79) constructs a service URL pointing back to the application and redirects the browser toCasProperties.serverLoginUrl. - Ticket validation: After authentication at the CAS server, the user returns with a
ticketparameter.BellaValidatorFiltervalidates this against the CAS server and maps attributes (ucid, displayName, email) to anOperatorinonSuccessfulValidation(lines 37-55). - Attribute mapping: The filter reads attribute names from
CasProperties(id-attribute, name-attribute, email-attribute) to populate theOperator. - Post-login routing: If the original request contained a
redirectparameter,BellaValidatorFilterstores it forBellaRedirectFilterto complete the navigation (lines 56-58).
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'sSessionManagerby 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:
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:
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:
<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:
@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
@ConditionalOnOAuthEnablewhenbella.login.type=oauthis set, usingOAuthLoginFilterto handle the authorization code flow and provider callbacks. - CAS activates via
@ConditionalOnCasEnablewhenbella.login.type=casis set, employing three specialized filters (BellaCasLoginFilter,BellaValidatorFilter,BellaRedirectFilter) to manage the ticket validation dance. - Both mechanisms store the resulting
Operatorobject through the sharedSessionManagerinterface, 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. 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".
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →