OIDC + Shiro + refresh_token: How?

264 views
Skip to first unread message

titou10...@gmail.com

unread,
Apr 24, 2018, 4:57:34 PM4/24/18
to Pac4j users mailing list
We are trying to implement OIDC with Apache Shiro, pac4j and the OIDC feature in a web application
The OP is WebSphere Liberty Profile (WLP)
The logic for the login goes well with Shiro (round trip to the OP for login form + usage of the callback in Shiro/pac4j)
Same for logout

Now, I spends hours trying to implement the logic related to the refresh_token to "refresh" the user profile when the token expires
Q:
- where/how to implement this logic?
- in a SecurityFilter?
- in an Authorizer?
- somewhere else?

I thing the main logic is the following:
1) Detect that the token expired: Either by using the OIDCProfile methods oe of by decoding the ID Token: This is the easy part
2) if expired perform an HTTP request to the OP to get an OIDC "RefreshResponse" (I was not able to find such a class in pac4j or elseqhwre, but TokenResponse can be used instead I guess)
  - how to get the client info to connect to the OP from the SecurityFilter/Authorizer...?
  - is there some facility in pac4j that wraps such a call that I can easily call?
3) on reception of the OIDC RefreshResponse/TokenResponse instance:
   - as the id_token and all token will change, how to "replace" the OIDC profile in memory/session/wherever it is saved/persisted? in the principal?...
  - is there some facility in pac4j that wraps such a call that I can easily call?

I spend hours googling without success for a solution
Any pointer to this kind of implementation would be greatly appreciated, A sample code of a Filter/Authorizer + shiro.ini config would be appreciated too.

Thanks in advance
 

Jérôme LELEU

unread,
Apr 25, 2018, 10:22:04 AM4/25/18
to titou10...@gmail.com, Pac4j users mailing list
Hi,

The refresh token logic could be developed in the OidcClient, it is responsible for the communication with the OpenID Connect IdP. In that case, you would need to check the expiration of the profile manually at some place, maybe in a specific ProfileManager and retrieve a new token from the refresh token.

Or, as we have a concept of isExpired at the CommonProfile level, you could put the expiration logic into the OidcProfile and the login would be triggered again when the expiration happens.

I think you should try both approaches and see what the result is.

Thanks.
Best regards,
Jérôme




--
You received this message because you are subscribed to the Google Groups "Pac4j users mailing list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

titou10 titou10

unread,
Apr 25, 2018, 3:16:35 PM4/25/18
to Jérôme LELEU, Pac4j users mailing list
Hi thanks for your answer (Sorry Jerome for the double answer, I didn't perform a "reply to all" initially..)

The refresh token logic could be developed in the OidcClient, it is responsible for the communication with the OpenID Connect IdP.
 
OK. I already have specific classes : "LibertyOidcProfile extends OidcProfile" and "LibertyOidcClient extends OidcClient<LibertyOidcProfile>" (mimic from GoogleOidcClient)
 
In that case, you would need to check the expiration of the profile manually at some place, maybe in a specific ProfileManager and retrieve a new token from the refresh token.

Could you be more precise? In what class/component should I::
- decode/decrypt the ID Token token and test if is is expired? : The OidcProfie is needed here to get the ID Token..
- implement the logic to perform the HTTPS call to the OIDC OP with the "RefreshToken" Request? : the information held by pac4j from the "OIDC Discovery" call is need here to perform the call (URL, credential)
- parse the RefreshToken Response and "replace/refresh" the OidcProfile and and Pac4jPrincipal + the Shiro Subject with the new data: Access Token, Refresh Token, ID Token + expiration time
I can't find the right place to perform those operations from the OidcClient, OidcProfile nor ProfileManager

Or, as we have a concept of isExpired at the CommonProfile level, you could put the expiration logic into the OidcProfile and the login would be triggered again when the expiration happens.

We do not want to trigger a new login when the ID Token expires. The Web session will expires in let say 30 mins, while the ID Token may expires every 5 mins, and just before it happens, the framework should performs the "refresh token"  logic as describe before in the background. The ID Token is used to initially get the user info + roles, and it is passed while calling REST API held in other "RS" servers

Denis

Jérôme LELEU

unread,
Apr 27, 2018, 4:59:57 AM4/27/18
to titou10 titou10, Pac4j users mailing list
Hi,

Before any technical implementation, we must be sure of what the different OIDC elements are meant for.

For me:
- the ID token is the identity of the authenticated user. Its expiration must be checked at login. I tend to think that we should re-login if it expires, but I'm not fully sure of that. This is what we do for Azure BTW. I think it should only be re-issued via a login process as it represents the authenticated user.
- the access token is a permission to access a REST API. It can be refreshed using the refresh token.

We are in the authorization code flow here, but things may vary with other flows.

So I don't fully agree with your vision.

Thanks.
Best regards,
Jérôme

titou10...@gmail.com

unread,
Apr 30, 2018, 4:36:12 PM4/30/18
to Pac4j users mailing list
Hi Jerome,
Thanks for your explanations
You are totally right, our view of the role and usage of the OIDC ID Token and Access Token were very wrong
The comments on this post on stack overflow are also very informative on the role of each token: https://stackoverflow.com/questions/34371782/oauth-2-0-authorization-server-and-access-tokens
The ID Token is "linked" to the Web session and the user must relogin when the ID Token or the Web session expires.
And in our case, the Access token returned from the OIDC login flow is just used to access remote REST resources. We'll check it's validity before performing REST call (and perform the OIDC/Oauth2 "refresh" flow if necessary). The AT will be added as an Authorization Bearer header in the REST calls. On the REST server side, it will be checked/decoded/validated  for validity and to perform authorize/reject the call based on the roles held in the token
Thanks a lot for your help and a big big thanks for what you've done with pac4j!
Denis
To unsubscribe from this group and stop receiving emails from it, send an email to pac4j-users...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages