<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <title>Liferay 7 authorization using openId connect and Keycloak</title>
  <link rel="self" href="https://liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=111924337" />
  <subtitle>Liferay 7 authorization using openId connect and Keycloak</subtitle>
  <id>https://liferay.dev/c/message_boards/find_thread?p_l_id=119785294&amp;threadId=111924337</id>
  <updated>2026-04-05T17:50:12Z</updated>
  <dc:date>2026-04-05T17:50:12Z</dc:date>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=118293393" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=118293393</id>
    <updated>2020-01-17T15:01:57Z</updated>
    <published>2020-01-17T15:01:57Z</published>
    <summary type="html">&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;body&gt;One thing I recently became aware of is that many of the Keycloak Restful API calls have a max query parameter to limit the number a of records that the call actually returns.&amp;nbsp; What the Keycloak documentation neglected to mention is that there is a default for this max parameter which seems to be normally set to&amp;nbsp;100 records.&amp;nbsp; I ran into this default setting on the one call I was making in my code above:&lt;br&gt;GET /{realm}/clients/{id}/roles/{role-name}/users&lt;br&gt;I had to add the setting of the max query parameter to overcome this limit of 100:&amp;nbsp;&lt;br&gt;&lt;pre&gt;&lt;code&gt;Map&amp;lt;string, string&amp;gt; params = new HashMap&amp;lt;string, string&amp;gt;();
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);&amp;lt;/string,&amp;gt;&amp;lt;/string,&amp;gt;&lt;/code&gt;&lt;/pre&gt;It would be better if the API didn't limit the call with a default unless specified by the developer.&lt;/body&gt;&lt;/html&gt;</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2020-01-17T15:01:57Z</dc:date>
  </entry>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=114123257" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=114123257</id>
    <updated>2019-06-25T17:00:31Z</updated>
    <published>2019-06-25T17:00:31Z</published>
    <summary type="html">I should mention to access the user&amp;#39;s roles in cloak there is one thing that must be done in order for the code I have above to work correctly.  When entering the username and email address for the user in Keycloak the username must match the first portion of the address before the @ sign.  This is because Liferay will use that first portion to create the  user&amp;#39;s screen name in Liferay.  My code uses the screen name to call back to Keycloak in order to retrieve the roles using Keycloak&amp;#39;s Rest API. I know its not a perfect solution and I may need to rethink this at a later date.</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-06-25T17:00:31Z</dc:date>
  </entry>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=112244506" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=112244506</id>
    <updated>2019-02-05T20:00:38Z</updated>
    <published>2019-02-05T20:00:38Z</published>
    <summary type="html">I summarized the work I did for this in a blog I recently posted: &lt;a href="https://community.liferay.com/blogs/-/blogs/liferay-keycloak-integration?_com_liferay_blogs_web_portlet_BlogsPortlet_redirect=https%3A%2F%2Fcommunity.liferay.com%3A443%2Fblogs%3Fp_p_id%3Dcom_liferay_blogs_web_portlet_BlogsPortlet%26p_p_lifecycle%3D0%26p_p_state%3Dnormal%26p_p_mode%3Dview%26_com_liferay_blogs_web_portlet_BlogsPortlet_cur%3D1%26_com_liferay_blogs_web_portlet_BlogsPortlet_delta%3D10"&gt;Liferay 7 SSO using OpenId Connect&lt;/a&gt;</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-02-05T20:00:38Z</dc:date>
  </entry>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111991561" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111991561</id>
    <updated>2019-01-11T17:28:34Z</updated>
    <published>2019-01-11T17:28:34Z</published>
    <summary type="html">&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;pre&gt;
GET /{realm}/roles/{role-name}/users&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;The post login hook i created simple redirects each authenticated
  user to the  authorization portlet.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;This may not be the best approach but it works.&lt;/p&gt;</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-01-11T17:28:34Z</dc:date>
  </entry>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111991208" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111991208</id>
    <updated>2019-01-11T17:09:53Z</updated>
    <published>2019-01-11T17:09:53Z</published>
    <summary type="html">Well I was able to work around this issue by using keycloaks rest api to
optain each role I was concerned with membership.  I was hoping to avoid
that but...</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-01-11T17:09:53Z</dc:date>
  </entry>
  <entry>
    <title>RE: Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111944232" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111944232</id>
    <updated>2019-01-07T14:13:40Z</updated>
    <published>2019-01-07T14:13:40Z</published>
    <summary type="html">Nobody know anything about this???</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-01-07T14:13:40Z</dc:date>
  </entry>
  <entry>
    <title>Liferay 7 authorization using openId connect and Keycloak</title>
    <link rel="alternate" href="https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111924336" />
    <author>
      <name>William Gosse</name>
    </author>
    <id>https://liferay.dev/c/message_boards/find_message?p_l_id=119785294&amp;messageId=111924336</id>
    <updated>2019-01-03T15:36:16Z</updated>
    <published>2019-01-03T15:36:16Z</published>
    <summary type="html">&lt;p&gt;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.  &lt;/p&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;HttpServletRequest request = lifecycleEvent.getRequest();&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;KeycloakPrincipal principal = (KeycloakPrincipal) request.getUserPrincipal();&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;if (principal != null) {&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;   String clientId = &amp;quot;aimportal&amp;quot;;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;   Set&amp;lt;String&amp;gt; roles = principal.getKeycloakSecurityContext().getToken().getResourceAccess(clientId).getRoles();&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;   for (String role : roles) {&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;       System.out.println(&amp;quot;role=&amp;quot; + role);&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;   }&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
  &lt;em&gt;
    &lt;strong&gt;}&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;But a get a &lt;em&gt;
    &lt;strong&gt;java.lang.ClassCastException:
      com.liferay.portal.kernel.servlet.ProtectedPrincipal cannot be
      cast to org.keycloak.KeycloakPrincipal&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I'd be happy if I could just get the JWT access token from the I'm
  assuming the request somehow.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;I'm sure Im incorrectly going about this so any suggestion would be
  greatly appreciated.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;</summary>
    <dc:creator>William Gosse</dc:creator>
    <dc:date>2019-01-03T15:36:16Z</dc:date>
  </entry>
</feed>
