Keycloak Advanced Integration: JWT Refresh, Admin API, SSO | ශ්‍රී ලංකා SC Guide

Keycloak Advanced Integration: JWT Refresh, Admin API, SSO | ශ්‍රී ලංකා SC Guide

ආයුබෝවන් කට්ටියටම! කොහොමද ඉතින් වැඩකටයුතු?

අද අපි කතා කරන්න යන්නේ software development වල, විශේෂයෙන්ම enterprise-grade applications හදනකොට නැතුවම බැරි security tool එකක් ගැන – ඒ තමයි Keycloak. බොහොමයක් දෙනෙක් Keycloak භාවිතා කරලා ඇති, මූලික Authentication සහ Authorization setup කරලා ඇති. ඒත්, production environment එකකට ගැලපෙන විදියට, advanced features එක්ක Keycloak integrate කරන්නේ කොහොමද කියලා කීයෙන් කී දෙනාද දන්නේ? අද අපි කතා කරන්නේ ඒ වගේ අත්‍යවශ්‍ය කරුණු කීපයක් ගැන: JWT lifecycle එක, tokens refresh කරන විදිය, Keycloak Admin API එක පාවිච්චි කරලා users සහ roles manage කරන විදිය, සහ multiple services අතර Single Sign-On (SSO) ගැඹුරින් තේරුම් ගන්න විදිය.

මේ tutorial එක අවසානෙදි, ඔයාලට පුළුවන් වෙයි වඩාත් robust, secure, සහ user-friendly applications හදන්න. ඉතින්, තවත් පරක්කු නොවී, අපි වැඩේට බහිමු!


JWT Lifecycle සහ Token Refresh යාන්ත්‍රණය (JWT Lifecycle & Token Refresh Mechanism)

Keycloak ගැන කතා කරනකොට JWT (JSON Web Token) කියන්නේ අත්‍යවශ්‍යම දෙයක්. User කෙනෙක් සාර්ථකව authenticate වුණාට පස්සේ, Keycloak එකෙන් tokens දෙකක් නිකුත් කරනවා: Access Token එකක් සහ Refresh Token එකක්.

Access Token

  • මේක තමයි ඔබගේ application එකේ protected resources access කරන්න භාවිතා කරන ප්‍රධාන token එක.
  • මේවා සාමාන්‍යයෙන් short-lived, කියන්නේ කෙටි කාලයකට (උදා: මිනිත්තු 5-10) විතරයි වලංගු.
  • Security සඳහා මේක ඉතාම වැදගත්. මොකද, මොකක් හෝ හේතුවකින් Access Token එකක් compromise වුණොත්, එහි වලංගු කාලය අඩු නිසා damage එක අවම කරගන්න පුළුවන්.

Refresh Token

  • මේක long-lived token එකක් (උදා: පැය කිහිපයක්, දින කිහිපයක්).
  • Access Token එක expired වුණාම, අලුත් Access Token එකක් ලබාගන්න මේක භාවිතා කරනවා.
  • ඒ කියන්නේ, user ට නැවත නැවත login වෙන්න ඕනෙ වෙන්නේ නැහැ. User session එක seamless (බාධාවකින් තොරව) පවත්වාගෙන යන්න මේක උදව් වෙනවා.

ඉතින්, මේ Token Refresh Mechanism එක වැඩ කරන්නේ මෙහෙමයි:

  1. Client (ඔබගේ Spring Boot application එක වගේ) එක Access Token එකක් අරන් protected resource එකකට request එකක් යවනවා.
  2. Resource server එක (ඔබගේ microservice එක) Access Token එක validate කරනවා.
  3. Access Token එක expired නම්, resource server එක 401 Unauthorized response එකක් return කරනවා.
  4. Client එක මේ 401 response එක detect කරලා, Refresh Token එක පාවිච්චි කරලා Keycloak එකෙන් අලුත් Access Token එකක් ඉල්ලනවා. මේකට grant_type=refresh_token කියන flow එක භාවිතා කරනවා.
  5. Keycloak එක Refresh Token එක validate කරලා, වලංගු නම්, අලුත් Access Token එකක් සහ සමහර විට අලුත් Refresh Token එකකුත් නිකුත් කරනවා.
  6. Client එක අලුත් Access Token එකත් එක්ක මුල් request එක නැවත යවනවා.

Spring Boot application එකක මේක implement කරන්න පුළුවන් එක් ක්‍රමයක් තමයි RestTemplate (හෝ WebClient) interceptors භාවිතා කිරීම. මෙන්න සරල pseudo-code එකක්:


public class KeycloakTokenInterceptor implements ClientHttpRequestInterceptor {

    private final KeycloakAccessTokenProvider tokenProvider;

    public KeycloakTokenInterceptor(KeycloakAccessTokenProvider tokenProvider) {
        this.tokenProvider = tokenProvider;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        // Current access token එක request header එකට දාන්න
        String accessToken = tokenProvider.getAccessToken(); // මේක token cache එකකින් ගන්න පුළුවන්
        request.getHeaders().add("Authorization", "Bearer " + accessToken);

        ClientHttpResponse response = execution.execute(request, body);

        // Access Token expired නම් (401 Unauthorized)
        if (response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
            // Refresh Token එක පාවිච්චි කරලා අලුත් Access Token එකක් ගන්න
            tokenProvider.refreshAccessToken();
            // අලුත් Access Token එකත් එක්ක request එක නැවත යවන්න
            request.getHeaders().set("Authorization", "Bearer " + tokenProvider.getAccessToken());
            return execution.execute(request, body);
        }
        return response;
    }
}

// KeycloakAccessTokenProvider class එකේ token refresh logic එක මෙහෙම වෙන්න පුළුවන්
public class KeycloakAccessTokenProvider {
    private String accessToken;
    private String refreshToken;
    private long accessTokenExpiry; // In milliseconds

    // ... constructor සහ initial token ලබාගැනීමේ logic එක ...

    public String getAccessToken() {
        if (System.currentTimeMillis() > accessTokenExpiry - 5000) { // Expiry එකට තත්පර 5කට කලින් refresh කරන්න
            refreshAccessToken();
        }
        return accessToken;
    }

    public synchronized void refreshAccessToken() {
        // Keycloak token endpoint එකට POST request එකක් යවන්න
        // grant_type=refresh_token, client_id, client_secret, refresh_token දාලා
        // Response එකෙන් අලුත් access_token, refresh_token, expires_in අරන් update කරන්න
        // HTTP client library එකක් (RestTemplate/WebClient) භාවිතා කරන්න
        // Error handling එකත් මෙතන වැදගත්
        System.out.println("Refreshing Access Token...");
        // Dummy refresh logic
        this.accessToken = "new_access_token_" + System.currentTimeMillis();
        this.refreshToken = "new_refresh_token_" + System.currentTimeMillis();
        this.accessTokenExpiry = System.currentTimeMillis() + 300 * 1000; // 5 minutes
    }
}

මේ වගේ implementation එකක් මගින් user ට නොදැනීම tokens refresh කරලා, uninterrupted session එකක් ලබාදෙන්න පුළුවන්. ඒත් මේක production environment එකකට යද්දි thread-safety, retry mechanisms, සහ robust error handling එක්ක හදන්න ඕනේ.


Keycloak Admin API එකෙන් User සහ Role Management (User & Role Management via Keycloak Admin API)

User account සහ role management කියන දේවල් සාමාන්‍යයෙන් Keycloak admin console එක හරහා කරනවා. ඒත්, සමහර වෙලාවට අපිට මේ දේවල් programmatically කරන්න සිද්ධ වෙනවා. උදාහරණයක් විදියට, ඔබගේ application එකේම user registration process එකක් තිබිලා, ඒ users ලව Keycloak එකට synchronize කරන්න ඕන නම්, නැත්නම් වෙනත් external system එකකින් user data එනවා නම්. මෙන්න මේ වගේ අවස්ථාවලට Keycloak Admin REST API එක තමයි විසඳුම.

Admin API එකට Authenticate වීම

Admin API එකට access කරන්න කලින් authentication වෙන්න ඕනේ. මේකට ක්‍රම කිහිපයක් තියෙනවා:

  • Client Credentials Flow: මේක තමයි වඩාත් සුදුසු ක්‍රමය. Keycloak එකේ confidential client එකක් හදලා, client ID සහ client secret පාවිච්චි කරලා token එකක් ගන්නවා. මේ token එක තමයි Admin API calls වලට භාවිතා කරන්නේ.
  • Admin User Login: Admin user කෙනෙක්ගේ username සහ password පාවිච්චි කරලා token එකක් ගන්නත් පුළුවන්. ඒත් මේක production වලට එතරම් සුදුසු නැහැ.

ප්‍රධාන Admin API Operations

Keycloak Admin API එක හුඟක් comprehensive. මෙතනදී අපි පොඩි උදාහරණ කීපයක් බලමු.

1. User කෙනෙක්ව Create කිරීම


// Keycloak Admin API Client library එකක් (උදා: keycloak-admin-client) භාවිතා කරන්න.
// නැත්නම් RestTemplate/WebClient එකෙන් direct REST calls යවන්න.

// Client Credentials flow එකෙන් token එකක් ගන්න
String adminAccessToken = keycloakAuthClient.getAdminAccessToken();

// User Representation object එකක් හදන්න
UserRepresentation newUser = new UserRepresentation();
newUser.setEnabled(true);
newUser.setUsername("[email protected]");
newUser.setFirstName("New");
newUser.setLastName("User");
newUser.setEmail("[email protected]");

// Password එක set කරන්න (තාවකාලික)
CredentialRepresentation passwordCred = new CredentialRepresentation();
passwordCred.setType(CredentialRepresentation.PASSWORD);
passwordCred.setValue("password123"); // Change this to a secure, temporary password
passwordCred.setTemporary(true); // User should change password on first login
newUser.setCredentials(Collections.singletonList(passwordCred));

// Keycloak Admin API එකට POST request එක යවන්න
// POST /auth/admin/realms/{realm}/users
// Headers: Authorization: Bearer {adminAccessToken}
// Body: newUser (JSON)

// Response එකෙන් user ID එක ගන්න නැත්නම් accession එක confirm කරගන්න

2. User කෙනෙකුට Role එකක් Assign කිරීම

User කෙනෙක්ව හැදුවට පස්සේ, අදාළ roles assign කරන්න ඕනේ.


// User ID එක සහ Role ID (නැත්නම් Role Name) දැනටමත් තියෙන්න ඕනේ.
String userId = "some-user-id";
String roleName = "app_user"; // මේක realm role එකක් වෙන්න පුළුවන්

// Realm එකේ role එකේ details ගන්න (GET /auth/admin/realms/{realm}/roles/{role-name})
// මේකෙන් role ID එක ලබාගන්න.
RoleRepresentation role = keycloakAdminClient.realm(REALM_NAME).roles().get(roleName).toRepresentation();

// User ට role එක assign කරන්න (POST /auth/admin/realms/{realm}/users/{id}/role-mappings/realm)
// Body: [ { "id": role.getId(), "name": role.getName() } ]

keycloakAdminClient.realm(REALM_NAME)
    .users()
    .get(userId)
    .roles()
    .realmLevel()
    .add(Collections.singletonList(role));

මේ වගේම user updates, deletions, user attributes management, group management වගේ දේවලුත් Admin API එකෙන් කරන්න පුළුවන්. මේක හොඳට ඉගෙනගත්තොත් Keycloak සහ ඔබගේ applications අතර seamless integration එකක් හදන්න පුළුවන්.


Multiple Services අතර Single Sign-On (SSO) Deep Dive

Single Sign-On (SSO) කියන්නේ user කෙනෙක් එක පාරක් authenticate වුණාට පස්සේ, එකම session එකක් තුළදී වෙනත් independent applications වලට නැවත login නොවී access කරන්න පුළුවන් යාන්ත්‍රණයක්. Keycloak කියන්නේ IdP (Identity Provider) එකක් විදියට වැඩ කරන නිසා, SSO implementation එක ඉතාම පහසුයි.

Keycloak SSO වැඩ කරන විදිය

සරලවම කිව්වොත්, Keycloak එක SSO කරන්නේ browser-based redirects සහ session cookies පාවිච්චි කරලා.

  1. පළමු Service එකට Access කිරීම: User කෙනෙක් ඔබේ microservice එකකට (උදා: Service A) access කරන්න හදනවා.
  2. Keycloak වෙත Redirect: Service A, user ව Keycloak login page එකට redirect කරනවා.
  3. Authentication: User, Keycloak එකේ authenticate වෙනවා (username/password, MFA, etc.).
  4. Keycloak Session Creation: සාර්ථක authentication එකකින් පස්සේ, Keycloak එක user ගේ browser එකේ session cookie එකක් (උදා: KEYCLOAK_SESSION) store කරනවා. මේක තමයි IdP session එක.
  5. Token සහ Service A වෙත Redirect: Keycloak එක tokens නිකුත් කරලා, user ව Service A එකට redirect කරනවා. Service A මේ tokens පාවිච්චි කරලා user session එක establish කරනවා.
  6. දෙවන Service එකට Access කිරීම: දැන් user, ඔබේ වෙනත් microservice එකකට (උදා: Service B) access කරන්න හදනවා.
  7. Keycloak වෙත Redirect (නැවතත්): Service B, user ව Keycloak login page එකට redirect කරනවා.
  8. Silent Authentication: මේ පාර, Keycloak එක detect කරනවා browser එකේ කලින් session cookie එක (KEYCLOAK_SESSION) තියෙනවා කියලා. ඒ නිසා, Keycloak එක user වට නැවත username/password අහන්නේ නැතුව, silent-authentication එකක් කරලා, අලුත් tokens ටිකක් නිකුත් කරලා, user ව Service B එකට redirect කරනවා.
  9. Seamless SSO: මේ විදියට, user ට එකම Keycloak realm එක යටතේ තියෙන ඕනෑම service එකකට නැවත login නොවී access කරන්න පුළුවන්.

Production-Ready SSO සඳහා වැදගත් කරුණු

  • Session Timeout Management: Keycloak realm එකේ idle timeout, Max lifespan වගේ settings තියෙනවා. මේවා ඔබේ application එකේ security policies වලට ගැලපෙන්න set කරන්න. Application service වල session timeouts Keycloak session timeouts වලට වඩා අඩු හෝ සමාන වීම වැදගත්.
  • Single Logout (SLO): User කෙනෙක් එක් service එකකින් logout වුණාම, Keycloak session එකත් destroy කරලා, අනිත් හැම service එකකින්ම logout කරන්න පුළුවන් වෙන්න ඕනේ. Keycloak මේක OIDC (OpenID Connect) සහ SAML protocols හරහා support කරනවා. Service side එකෙන් Keycloak logout endpoint එක call කරන්න ඕනේ.
  • Client Configuration: Keycloak client එකක් හදනකොට, Standard Flow Enabled, Direct Access Grants Enabled, Service Accounts Enabled වගේ settings හරියට තෝරාගන්න. Valid Redirect URIs සහ Web Origins හරියට set කරන්න අමතක කරන්න එපා. Multiple services සඳහා එකම realm එකක් සහ client group එකක් භාවිතා කිරීම, නමුත් එක් එක් service සඳහා අවශ්‍ය නම් වෙනම clients භාවිතා කිරීම හොඳ පුරුද්දක්.
  • Session Pinning: සමහර වෙලාවට load balancers හරහා යනකොට session pinning (sticky sessions) අවශ්‍ය වෙනවා. ඒකෙන් එකම user ගේ requests හැමදාම එකම Keycloak node එකකට යොමු කරනවා. Distributed Keycloak deployments වලදී මේක වැදගත්.

SSO කියන්නේ user experience එකට ඉතාම වැදගත් දෙයක්. ඒ වගේම, developer කෙනෙක් විදියට මේක නිවැරදිව implement කරන එක ඔබේ application එකේ security සහ usability දෙකම වැඩි කරනවා.


අවසාන වශයෙන් (In Conclusion)

ඉතින්, අද අපි කතා කළේ Keycloak integration වල production environment එකකට ගැලපෙන අත්‍යවශ්‍ය කරුණු කීපයක් ගැන. JWT lifecycle එක සහ token refresh mechanisms වලින් seamless user sessions පවත්වාගෙන යන හැටි, Keycloak Admin API එක පාවිච්චි කරලා programmatic user සහ role management කරන හැටි, සහ multiple Spring Boot services අතර Single Sign-On (SSO) ගැඹුරින් වැඩ කරන හැටි අපි බැලුවා.

මේ concepts හරියට තේරුම් අරන් implement කරන එකෙන්, ඔයාලට පුළුවන් වෙයි වඩාත් secure, scalable, සහ user-friendly applications හදන්න. මේවා හුදෙක් conceptual දැනුම විතරක් නෙමෙයි, දිනපතා coding කරනකොට හුඟක් ප්‍රයෝජනවත් වෙන practical skills.

මේ ගැන ඔයාලගේ අදහස්, ප්‍රශ්න පහළින් comment කරන්න. මේ ගැන තවත් දැනගන්න ඕන නම්, නැත්නම් වෙනත් topics ගැන කතා කරන්න ඕන නම්, ඒවත් කියන්න. අපි ඊළඟ පෝස්ට් එකෙන් හම්බවෙමු! සුබ දවසක්!