Ask Questions and Find Answers
Important:
Ask is now read-only. You can review any existing questions and answers, but not add anything new.
But - don't panic! While ask is no more, we've replaced it with discuss - the new Liferay Discussion Forum! Read more here here or just visit the site here:
discuss.liferay.com
RE: Liferay 7 authorization using openId connect and Keycloak
I'm using the OpenId Connect plugin, https://web.liferay.com/marketplace/-/mp/application/78695724, in combination with Keycloak to perform SSO authentication. This part is working out great.
I'm trying to write a post login hook that will get me the roles that I have setup in Keycloak for an individual user that was authenticated by the plugin. I thought I could use the Keycloak API to get this information but now I'm not so sure about that. I tried the following:
HttpServletRequest request = lifecycleEvent.getRequest();
KeycloakPrincipal principal = (KeycloakPrincipal) request.getUserPrincipal();
if (principal != null) {
String clientId = "aimportal";
Set<String> roles = principal.getKeycloakSecurityContext().getToken().getResourceAccess(clientId).getRoles();
for (String role : roles) {
System.out.println("role=" + role);
}
}
But a get a java.lang.ClassCastException: com.liferay.portal.kernel.servlet.ProtectedPrincipal cannot be cast to org.keycloak.KeycloakPrincipal
I'd be happy if I could just get the JWT access token from the I'm assuming the request somehow.
I'm sure Im incorrectly going about this so any suggestion would be greatly appreciated.
By the way I did this keycloak/liferay integration using a post login hook and custom porlet in combination with the openid connect plugin form the marketplace. The openid connect plugin would authenticate the user using a jwt access token that was provided by keycloak. It also would create the user account within liferay if it did'nt exist. Just aheads up, in keycloak you need to have users that have a username, firstname, lastname and email address in order for them to be added into liferay by the plugin.
Also roles in keycloak should asscociated directly with the users in keycloak. The keycloak rest api, although extensive, is somewhat quirky. The expedient way that I could find to get users roles was to make the following restful call:
GET /{realm}/roles/{role-name}/users
This call needs to be proceeded by a restful call to get the admin users access token. I used a Jersey client inside my custom authorization portlet to make thes to calls. Inside this same portlet a also used the liferay apis to add the current user to the appropriate roles if needed within liferay. I would also remove a role from a user in liferay if they no longer had it in keycloak.
The authorization portlet would then redirect the users to the appropriate landing page in liferay or an error page if they had no valid roles other then user.
The post login hook i created simple redirects each authenticated user to the authorization portlet.
This may not be the best approach but it works.
GET /{realm}/clients/{id}/roles/{role-name}/users
I had to add the setting of the max query parameter to overcome this limit of 100:
Map<string, string> params = new HashMap<string, string>();
params.put(MAX, AUTH_SERVICE_ROLES_MAX);
String roleUserPath = AUTH_SERVICE_ROLES_PATH + SLASH + authServiceRole + USERS_PATH;
Response response = client.get(AUTH_SERVICE_URL, roleUserPath, MediaType.APPLICATION_JSON, params, accessToken);</string,></string,>
It would be better if the API didn't limit the call with a default unless specified by the developer.
Powered by Liferay™