Securing My Stack: Features and Experience Integrating Asgardeo, Ballerina, and Choreo
Source: Dev.to
Introduction: Building a Secure Microservice Gateway
For my Secure Gateway Project—integrating a React Frontend with a Ballerina Backend on WSO2 Choreo—I chose WSO2 Asgardeo as the core Identity Provider (IDP). My goal was to leverage a modern, cloud‑native Identity and Access Management (CIAM) solution that seamlessly handles the complexities of OAuth 2.0 and OpenID Connect (OIDC).
This post details the specific features of Asgardeo I utilized and explores my hands‑on experience integrating them into a secure microservice architecture.
Architecture at a Glance
Our simple stack provided layered security:
| Component | Technology | Security Role |
|---|---|---|
| Frontend | React (Vite) | Initiates the OIDC flow and handles user session. |
| Backend API | Ballerina | Contains protected business logic, secured by a JWT Validator. |
| API Gateway | Choreo Connect | First security layer; validates the JWT before routing. |
| IDP | Asgardeo | Issues the authenticated JSON Web Token (JWT). |
Feature 1: Seamless SPA Setup and PKCE
My Experience: Intuitive and Secure Configuration
I defined my application as a Single Page Application (SPA). This choice instantly configured the necessary security protocol: the Authorization Code flow with PKCE (Proof Key for Code Exchange).
- PKCE is Critical: For public clients like an SPA (which cannot securely store a client secret), PKCE prevents code‑interception attacks. Asgardeo automatically mandates PKCE when the SPA template is chosen, providing immediate security without manual configuration.
- Redirect Management: Configuring the Authorized Redirect URLs (e.g.,
https:///callback) was simple and clear, which is crucial for preventing authentication flow breakage.
Feature 2: The React SDK (@asgardeo/auth-react)
My Experience: Token Reliability in a Reactive App
The official Asgardeo SDK for React simplified login/logout integration and session management.
useAuthContextHook: Gives instant access to the user’s authentication state (isAuthenticated) and session data.- Token Reliability: Relying on reactive state for the access token can cause race conditions. The SDK’s asynchronous
getAccessToken()method reliably fetches the final, valid token just before an API call, ensuring theAuthorization: Bearer <token>header is always current.
// Reliable way to fetch the token just before the API call
const fetchData = async () => {
const token = await getAccessToken();
const apiResponse = await fetch(apiUrl, {
headers: {
Authorization: `Bearer ${token}`
}
});
// ... handle response
};
Feature 3: JWT Access Token Generation and Validation
My Experience: Uncovering the Issuer Conflict
My Ballerina API required a JWT for validation. Asgardeo issued a valid JWT, but its iss claim presented a challenge:
- Problematic Claim: The Issuer (
iss) claim contained the full token endpoint URL (https://.../oauth2/token). - Standard Expectation: My validators were initially configured to expect only the base URL (
https://.../t/maheshadinushan).
Inspecting the actual token payload revealed the mismatch. I had to configure both the API Gateway (Choreo) and the Ballerina service to trust the full endpoint URL (.../oauth2/token) to match the token generated by Asgardeo. This adjustment resolved the JWT validator deadlock.
