Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable Multiple login at Keycloak

It is possible to disable multiple login at Keycloak?

Example:

I logged in on my browser at my PC and I do a login on my mobile phone... at this moment, keycloak invalidade the token of my other browser.

It is possible?

like image 270
Leonardo Oliveira Avatar asked Apr 11 '17 13:04

Leonardo Oliveira


2 Answers

Update:

This feature has been implemented in keycloak version 17.
See: https://github.com/keycloak/keycloak/issues/10077

Old workaround:

Keycloak does not have this feature implemented yet. If you want you can create your own custom authenticator, for that you should have sound knowledge of keycloak codebase. I was facing the same issue and came up with a workaround.

Keycloak maintains active sessions of a user as shown below: enter image description here

Every time a user logs in through different device, a session is added in the above list, we can use the above info to limit the user session to one.

I'm heavily making use of keycloak admin rest APIs to get the session-related data and to delete the session: link here

Make an API request to your server when a user logs in:

client.js

componentDidMount(){
      let auth = await keycloak.init({onLoad: "check-sso"});     
      if(auth){
         const {data} = await axios.get(`/check_session/${keycloak.subject}`);
         this.setState({isSessionValid: data.isSessionValid})
        }
      }

  render(){
    return(
      {this.state.isSessionValid ? 
        <YourComponent/> : 
        <div> You are already logged in!</div>
      }
    )
  }

server.js

const baseUrl = 'http://localhost/auth';
const realm = 'myRealm'

  // check session of user with same credentials from different devices
export const checkUserSession = async userId => {

    // initialize access token
    await initializeAccessToken(baseUrl); // check admin rest api docs of keycloak

    // get all active sessions of user
    const sessions = await getUserActiveSessions(baseUrl, realm, userId); // check admin rest api docs of keycloak

    // check if any session exists
    if (sessions && sessions.length > 1) {
      // sort with start time in descending order
      sessions.sort((a, b) => b.start - a.start);
      const currentSession = sessions[0]; // current logged in user's session
      const previousSession = sessions[1]; // previously active user's session
     
    /* I'm preventing current user to log in, for your case you can delete 
          the old session of this user here */   
     
     await deleteUserSession(baseUrl, realm, currentSession.id); // check admin rest api docs of keycloak
        return { isSessionValid: false, sessionData:previousSession };
    }
    // user logged in first time
    return { isSessionValid: true };
  };
like image 94
Naman Parashar Avatar answered Oct 06 '22 21:10

Naman Parashar


Looks like a lot of Keycloak users are interested in this feature so I am posting an answer which I found on my conducted research, this feature implemented by unofficial developer and here is what he shared

You can get the authenticators from my cloned branch: https://github.com/mfdewit/keycloak/tree/KEYCLOAK-849-configurable-session-limits/services/src/main/java/org/keycloak/authentication/authenticators/sessionlimits

I've created 2 authenticators:

`RealmSessionLimitsAuthenticator`: limits the total number of sessions for a realm.
`UserSessionLimitsAuthenticator`: limits the number of session per user account and per client.

For now I advise you to copy them (including the factories) to your own project and make sure they are referenced in META-INF/services. Also, change the AuthenticationFlowError.SESSION_LIMIT_EXCEEDED error to some value that exists in your Keycloak version. SESSION_LIMIT_EXCEEDED is added by me and only exists on my feature branch.

The downside is that you cannot provide the user proper feedback in case his session is denied.

If you have any questions on how these should be used, let me know!

Regarding the status of this task: I still have to write the integration tests before I can submit the merge request. But I'm planning to finish this soon. If anyone want to help writing these tests, I'd be grateful.

Still keycloak official JIRA i didn't find if they incorporated this feature in any recent version of Keycloak

Source

https://github.com/mfdewit/keycloak/tree/KEYCLOAK-849-configurable-session-limits/services/src/main/java/org/keycloak/authentication/authenticators/sessionlimits

like image 3
Subodh Joshi Avatar answered Oct 06 '22 19:10

Subodh Joshi