20

We plan to use keycloak to secure a bunch of web apps, some written in Java, some in JavaScript (with React).

After the user is logged in by keycloak, each of those web apps needs to retrieve the user that is logged in and the realm/client roles that the user has.

  • For Java apps, we tried the keycloak Java API (request -> KeycloakSecurityContext -> getIdToken -> getPreferredUsername/getOtherClaims). They seem to work fine
  • For JavaScript apps, we tried the following code, but could not get Keycloak to init successfully (Note this is in web app code after the user is already authenticated by keycloak, the app is only trying to retrieve who logged in with what roles):

    var kc = Keycloak({
        url: 'https://135.112.123.194:8666/auth',
        realm: 'oneRealm',
        clientId: 'main'
    }); 
    
    //this does not work as it can't find the keycloak.json file under WEB-INF
    //var kc = Keycloak('./keycloak.json'); 
    
    kc.init().success(function () {
        console.log("kc.idToken.preferred_username: " + kc.idToken.preferred_username);
        alert(JSON.stringify(kc.tokenParsed)); 
        var authenticatedUser = kc.idTokenParsed.name; 
        console.log(authenticatedUser);  
    }).error(function () {
        window.location.reload();
    });
    

I assume it would be fairly common that web apps need to retrieve current user info. Anyone knows why the above code didn't work?

Thanks.

epascarello
  • 204,599
  • 20
  • 195
  • 236
Alex
  • 351
  • 1
  • 3
  • 7

3 Answers3

27
    <script src="http://localhost:8080/auth/js/keycloak.js" type="text/javascript"></script>
<script type="text/javascript">
const keycloak = Keycloak({
    "realm": "yourRealm",
    "auth-server-url": "http://localhost:8080/auth",
    "ssl-required": "external",
    "resource": "yourRealm/keep it default",
    "public-client": true,
    "confidential-port": 0,
    "url": 'http://localhost:8080/auth',
    "clientId": 'yourClientId',
    "enable-cors": true
});
const loadData = () => {
    console.log(keycloak.subject);
    if (keycloak.idToken) {
        document.location.href = "?user="+keycloak.idTokenParsed.preferred_username;
        console.log('IDToken');
        console.log(keycloak.idTokenParsed.preferred_username);
        console.log(keycloak.idTokenParsed.email);
        console.log(keycloak.idTokenParsed.name);
        console.log(keycloak.idTokenParsed.given_name);
        console.log(keycloak.idTokenParsed.family_name);
    } else {
        keycloak.loadUserProfile(function() {
            console.log('Account Service');
            console.log(keycloak.profile.username);
            console.log(keycloak.profile.email);
            console.log(keycloak.profile.firstName + ' ' + keycloak.profile.lastName);
            console.log(keycloak.profile.firstName);
            console.log(keycloak.profile.lastName);
        }, function() {
            console.log('Failed to retrieve user details. Please enable claims or account role');
        });
    }
};
const loadFailure =  () => {
     console.log('Failed to load data.  Check console log');
};
const reloadData = () => {
    keycloak.updateToken(10)
            .success(loadData)
            .error(() => {
                console.log('Failed to load data.  User is logged out.');
            });
}
keycloak.init({ onLoad: 'login-required' }).success(reloadData);
</script>

simple javascript client authentication no frameworks. for people who are still looking...

lolesque
  • 10,693
  • 5
  • 42
  • 42
Keshav Sharma
  • 483
  • 4
  • 7
  • 2
    Your post helped me realize that I don't need to call .loadUseProfile() , I can just use idTokenParsed....amazing , thanks!! – julianm Jun 16 '20 at 22:46
  • 1
    Please help me, I used your code to login but I keep getting re-login loop in my page. How can I avoid tthat? – iamatsundere181 Jul 14 '21 at 10:59
11

Your code asks the Keycloak client library to initialize, but it doesn't perform a login of the user or a check if the user is already logged in.

Please see the manual for details: http://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter

What your probably want to do:

  • Add check-sso to the init to check if the user is logged in and to retrieve the credentials keycloak.init({ onLoad: 'check-sso' ... }). You might even use login-required.

  • Make sure that you register a separate client for the front-end. While the Java backend client is of type confidential (or bearer only), the JavaScript client is of type public.

You find a very minimal example here: https://github.com/ahus1/keycloak-dropwizard-integration/blob/master/keycloak-dropwizard-bearer/src/main/resources/assets/ajax/app.js

Alternatively you can register a callback for onAuthSuccess to be notified once the user information has been retrieved.

Once you use Keycloak in the front-end, you will soon want to look in bearer tokens when calling REST resources in the backend.

ahus1
  • 5,782
  • 24
  • 42
  • Your [link](https://keycloak.gitbooks.io/documentation/securing_apps/topics/oidc/javascript-adapter.html) has been expired. Can you provide a new one please? – valijon Feb 19 '18 at 05:05
-1

You might have solved the problem by this time. I hope this answer help rest of the people in trouble.

when you use JavaScript Adopter Below javascript should be added in of html page.

    <script src="http://localhost:8080/auth/js/keycloak.js"></script>
            <script>
            /* If the keycloak.json file is in a different location you can specify it: 

Try adding file to application first, if you fail try the another method mentioned below. Both works perfectly.

            var keycloak = Keycloak('http://localhost:8080/myapp/keycloak.json'); */    

/* Else you can declare constructor manually  */
                var keycloak = Keycloak({
                    url: 'http://localhost:8080/auth',
                    realm: 'Internal_Projects',
                    clientId: 'payments'
                });


                keycloak.init({ onLoad: 'login-required' }).then(function(authenticated) {
                    alert(authenticated ? 'authenticated' : 'not authenticated');
                }).catch(function() {
                    alert('failed to initialize');
                });    

                function logout() {
                    //
                    keycloak.logout('http://auth-server/auth/realms/Internal_Projects/protocol/openid-connect/logout?redirect_uri=encodedRedirectUri')
                    //alert("Logged Out");
                }
             </script>

https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter Reference Link.

Note : Read the comments for 2 methods of adding json credentials.

Deepa MG
  • 188
  • 1
  • 15