When calling the WSO2 Identity Server 5.3.0 SessionManagementService the operation removeSession required a sessionId parameter. What exactly is the sessionId in that context (e.g. is it the value stored in a cookie e.g. "commonAuthId").
Background: Can this admin service function be used to terminate a session of a user?
Yes, you can use this admin service to terminate the session of a user. Here is the method that does it[1].
However a there is a condition,
Any user with login permission can call the removeMySession(String sessionId) method and terminate his own session.
To terminate the user session of another user, the user calling the admin service should have "/permission/admin/manage/identity/authentication/session/delete" permission.
The sessionId parameter that needs to be sent to [1] is the SHA256 Digest of the commonAuthId cookie value.
That is,
String sessionId = DigestUtils.sha256Hex(commAuthIdCookieValue);
where sessionKey is the value of the commonAuthId cookie.
[1] https://github.com/wso2/carbon-identity-framework/blob/70d5fb1e6db5a4bad2e309d8284f559a99e4feb0/components/authentication-framework/org.wso2.carbon.identity.application.authentication.framework/src/main/java/org/wso2/carbon/identity/application/authentication/framework/services/SessionManagementService.java#L36-L36
[2] https://commons.apache.org/proper/commons-codec/archives/1.7/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha256Hex(java.lang.String)
Related
First let me describe the setup:
We have a frontend Angular based product from a different client team (not part of code we can easily modify), and a backend django based API server.
The front end logs in to a keycloak server, and when logged in, the backend gets an Auth header with a bearer token in every request.
From this, we are able to identify the logged in user as follows (using python-keycloak):
ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']
This is obviously very wasteful since it needs an extra network request to keycloak everytime - so we create a django user session instead and use that for session management.
Now when it comes to logging out, when the user logs out from the front end, we need to void the django session.
I've setup the "Back channel logout URL" on the keycloak realm settings to call some endpoint on the django server.
The endpoint gets called on logout, and it gets a "logout_token" value in the arguments.
Now I'm not sure how I am supposed to identify which user is logging out based on this token. How can this be done?
Thanks in advance...
I am not 100% sure about the soundness of you architecture. Nonetheless, regarding your particular question:
ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']
From the Keycloak book:
preferred_username This is the username of the authenticated user. You should avoid this
as a key for the user as it may be changed, and even refer to a
different user in the future. Instead, always use the sub field for
the user key.
From the OpenID connect specification one can read that:
OPs send a JWT similar to an ID Token to RPs called a Logout Token to
request that they log out. ID Tokens are defined in Section 2 of
[OpenID.Core].
The following Claims are used within the Logout Token:
iss REQUIRED. Issuer Identifier, (...)
sub OPTIONAL. Subject Identifier,(...)
aud REQUIRED. Audience(s), (...)
iat REQUIRED. Issued at time, (...)
jti REQUIRED. Unique identifier for the token, (...)
(...)
sid OPTIONAL. Session ID - String identifier for a Session. This represents a Session of a User Agent or device for a logged-in End-User at an RP. (..)
A Logout Token MUST contain either a sub or a sid Claim, and MAY contain both. If a sid Claim is not present, the intent is that all sessions at the RP for the End-User identified by the iss and sub Claims be logged out.
So you can try to use the claim 'sub', which is the unique identifier of the authenticated user. You would (probably) need to create the mapping between 'sub' and 'user' in your backend. Alternatively, you could use the same logic but applying it to 'sid' instead. There you would map the ID session of Keycloak to your own ID session.
However, my question is:
The front end logs in to a keycloak server, and when logged in, the
backend gets an Auth header with a bearer token in every request.
From that bearer token (which I am assuming to be an access token) can't you simply get 'preferred_username' (or better the 'sub' claim) from there? that would not require any extra call to the Keycloak server.
Django rest framework
I'm setting the session key once a user logins in
request.session['id'] = 1
Then when I try to access it in the class view like
id = request.session.get('id', 0)
It is null [0] if the end-point call is made from the browser but it returns 1 if end-point call is from postman...
I need your guidance...
Session cookies are browser-specific - they are only sent back to the server if the request comes from the same browser that received the cookie in the first place.
Postman is not a browser - it is simply making raw HTTP requests. It will not send any cookies back, so of course you will not see session data.
This behavior is entirely expected and by design. Sessions are only persisted per-browser.
If you want to make API calls and authenticate them, you should use token authentication instead, which can be passed in the Authorization header of requests and is not tied to a browser session.
I am working with OIDC and WSo2IS-5.7.0. I Want to implement rp initiated global logout (I want to terminate the session from RP and as well as OP or WSO2 in my case.) When user clicks on logout button, I am redirecting the user to this URL :
https://myserver:9443/oidc/logout?id_token_hint=<idtoken>&post_logout_redirect_uri=https://myotherserver.com/myapp/index
It is working fine and user is redirected to login page of wso2. My client consider it not secure and want to do the same without being send id_token to front end. Is it possible with wso2is-5.7.0?
If yes, how?
If no, isn't it insecure that we send id token to FE? anyone can use it to make API call?
It is not possible. In WSO2 implementation we use the id_token_hint to extract the client_id from the id_token (sent as the id_token_hint). This is necessary to retrieve the service provider information for which the id_token was issued to.
Otherwise we don't have a way to validate whether the value sent in post_logout_redirect_uri is a registered callback for the service provider.
So if we omit the id_token_hint, we cannot validate the post_logout_redirect_uri sent which will open up another security hole allowing redirection to untrusted uris.
I have third party thrift services which need to check if user is authenticated using wso2 IS. I am using IS's thriftAuthenticator to authenticate a user and it returns me an authToken.
What I need is the JsessionId for the user and then for each corresponding call pass that JSessionId around and use an aspect to check if that Id has not expired.
My question is how can I find if the JSessionId is still valid for a user and also what is the timeout for that session.
If there are authentication failure exception, client side code can be implemented to retry again by retrieving new thrift sessionid. So, you do not need to worry about session timeout in the server side.
I have a 1.10.1.1 Magento Enterprise version running and tried out the webservice. If I correctly login I get a session id which I can use to make further calls to the web service.
If I leave either the user or password field empty or both empty and want to login I also get a session id. But if I then want to call another method with this session id I get the message I have to relogin.
If I use wrong credentials (both user and password are filled with something) I get a message "Access denied".
So why do I get a session id I can't use if i leave one field (user/password) empty and why don't I get a message "Acces denied" then? Is this an error?