Remove Cookies in Worklight Adapter : multiple sessions using same adapter based authentication - cookies

I am using Worklight Adapters and using Authentication based adapter, which verify credential via a third party webservice (grails server).
When testing with one user, every thing is fine, but once I start using multiple users accounts, I found that all users connect to the same session, with the same Cookie JSESSIONID
I think worklight adapter is adding cookies from previous requests, and that's equivalent to a browser connecting to différent accounts, without removing old cookies / logging out.
When debugging, I can see that I have in the authentication request response headers, when the first user login:
"Set-Cookie":"JSESSIONID=63850CB333E7C279DC6D5B1D973B21E7; Path=/"
and when the second user login, there is no longer "Set-Cookie" header in the response.
Anyone have a solution, or workarounds ?
How can I force worklight to remove existing cookies when connecting to the authentication webserver ?

In your adapter procedure you should add the attribute connectAs="endUser". This way each user will create a unique connection to the authentication backend and they will not share the same session ID.

I force a logout on window close. Something like this:
function wlCommonInit() {
window.onbeforeunload = function() {
WL.Logger.debug("logging out");
WL.Client.logout();
};
}

Related

OIDC js library reponse cookies are not stored and not attaching for subsequent requests

I am using authcodeflow with PKCE.
Using OIDC js library in the frontend, making calls to adfs getting an auth code and then calling my backend api. The backend api which calls adfs server get the access token and the backend api returns the token as a cookie to the frontend. I can see the cookie in response headers. but That cookie is not stored in browser and not getting added for subsequent requests. I have tried with samesite with all modes -> Lax, None,Strict and not setting.
Is this an issue with OIDC js library or is it blocking the cookies to store in browser?
Update:
Below are the observation with my analysis
Since the OIdc-client-js does not have an option to set flag "withCredentials" to true for the requests. There are no cookies send in the request and response cookies are ignored for the cross origin requests.This changes are marked as enhancement and still not completed in thier github repo.
https://github.com/IdentityModel/oidc-client-js/issues/1062
Is there any way to achieve with this library? or any other libraries for OIDC js
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
So you are issuing a cookie from an API domain that is a sibling of the WEB domain:
web.mycompany.com
api.mycompany.com
Cookie domain = .mycompany.com
POSSIBLE CAUSES FOR COOKIE BEING DROPPED
Maybe it is the withCredentials flag or maybe due to a lack of user gesture, since the user has not done anything explicit to navigate to api.mycompany.com, such as a browser navigation or clicking a link?
FORCING WITHCREDENTIALS
You can override the prototype like this in order to add the withCredentials property. This is a little hacky but you could limit usage based on the URL and it should let you know whether setting withCredentials resolves your problem:
let open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url) {
open.apply(this, arguments);
this.withCredentials = true;
}
PROXYING VIA WEB DOMAIN WILL HAVE FEWER COOKIE ISSUES
In my blog post I do something similar to proxy messages containing a refresh token. I use the web's exact domain though, rather than using an API subdomain. This will never be impacted by browser restrictions.

How can I remove session for specific user for specific ServiceProvider in WSO2 IS?

There is any webservice providing by WSO2 Identity server, to remove a session for specific user to specific ServiceProvider?
I am using SAMLSSO for many web application and they all are integrating with WSO2 server.
Now let's say scenario is,User is login with 2 application at the same time. I want to logout it from one application.
There is one service provided by logout and it's providing single logout and session will be remove for all application. There is webservice provided by IS or way to achieve logout for one specific application ?
What you are asking is to have the capability of removing a specific participant from the session created in the Identity Server side. I don't see a straight forward way (OOTB) of achieving this.
Closest you can achieve is as below.
Make your application perform a forceAuth. ForceAuth will request for user credentials despite having the cookies in the browser. (This will prevent the user from experiencing the SSO comfort. Still you can authenticate against the IS)
Prevent the application from sending an SLO request to WSO2. Rather, terminate the self(application) session upon logout.
When your application really wants to perform an SLO (logout all the applications, not just yours), your application can send an SLO request to the Identity Server.
Performing a force authentication :
SAML - Send forceAuth=true as a query paramter in your login request. Or else change the SAML AuthenricationRequest payload body to indicate a force authentication as in the spec(Line 2042).
OIDC - Send prompt=login as an additional query parameter in the /authorization request.
You can do this by calling the REST API and SOAP API provided by WSO2 IS. This will remove the session at WSO2 IS but I'm not sure if it will also trigger the SLO to other service providers or not.
Reference:
https://is.docs.wso2.com/en/latest/develop/calling-admin-services/
https://is.docs.wso2.com/en/latest/develop/session-mgt-rest-api/
Trigger a SOAP request getUserProfile from the UserProfileMgtService.wsdl. The default user profile will be 'default' or you can put the customized profile name you used. This will return the details. Grab the user id from this.
Trigger a GET to the API: /{user-id}/sessions with the user-id from step 1 to get the list of all active sessions this user currently have. Go through the list of sessions and find the session ID of the Service Provider you need to clear.
Trigger a DELETE request to API: /{user-id}/sessions/{session-id} with the user id from step 1 & session id from step 2

Django REST framework - prevent data access for user view?

In my api, I have a /users endpoint which currently shows (eg address) details of all users currently registered. This needs to be accessed by the (Ember) application (eg to view a user shipping address) but for obvious reasons I can't allow anyone to be able to view the data (whether that be via the browsable api or as plain JSON if we restrict a view to just use the JSONRenderer). I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
Am I missing something?
UPDATE
Hi, I wanted to come back on this.
For authentication on the Ember side I'm using Ember Simple Auth and token based authentication in Django. All is working fine - I can log into the Ember app, and have access to the token.
What I need to be able to do is to access the user; for this I followed the code sample here https://github.com/simplabs/ember-simple-auth/blob/master/guides/managing-current-user.md
I have tested the token based authentication in Postman, using the token for my logged in user - and can access the /users endpoint. (This is returning all users - what I want is for only the user for whom I have the token to be returned but that's for later!).
The question is how to do I pass the (token) header in any Ember requests, eg
this.store.findAll('user') .... etc
This is clearly not happening currently, and I'm not sure how to fix this.
UPDATE
Fixed it. Turns out that the authorize function in my application adapter was not setting the headers, so have changed the code to set the headers explicitly:
authorize(xhr) {
let { access_token } = this.get('session.data.authenticated');
if (isPresent(access_token)) {
xhr.setRequestHeader('Authorization', `Token ${access_token}`);
}
},
headers: computed('session.data.authenticated.token', function () {
const headers = {};
if (this.session.isAuthenticated) {
headers['Authorization'] = `Token ${this.session.data.authenticated.token}`
}
return headers;
})
Ember is framework for creating SPAs. These run in the browser. So for Ember to get the data, you have to send the data to the browser.
The browser is completely under the control of the user. The browser is software that works for them, not for the owner of the website.
Any data you send to the browser, the user can access. Full stop.
If you want to limit which bits of the data the user can read from the API, then you need to write the logic to apply those limits server-side and not depend on the client-side Ember code to filter out the bits you don't want the user to see.
I don't think I can use authentication and permissions, since the application needs to log a user in from the front end app (I am using token based authentication) in the first instance. If I use authentication on the user view in Django for instance, I am unable to login from Ember.
This doesn't really make sense.
Generally, this should happen:
The user enters some credentials into the Ember app
The ember app sends them to an authentication endpoint on the server
The server returns a token
The ember app stores the token
The ember app sends the token when it makes the request for data from the API
The server uses the token to determine which data to send back from the API

EmberJS - Handling 3rd party redirect authentication

I'm using ember-simple-auth for my Ember app, but I don't have an API endpoint to authenticate users, rather it does a page redirect to the form and signs a user in, then redirects back to my app. (I don't own the authentication)
After authentication, it gets redirected back to me, so I know on the server side when a user has been successfully authenticated. How do I manually authenticate the users' session when they are redirected back to my app?
Currently I did a hack to write two cookies: ember_simple_auth:access_token and ember_simple_auth:authenticator.
I think setting up the session store manually is an ok solution in this scenario as that will trigger the session to be restored after the redirect (which is on startup of the Ember application). I'd maybe configure a custom authenticator that redirects to the external login page in the authenticate method. That way you have that redirect centralized and it will also be triggered automatically whenever Ember Simple Auth automatically enforces session authentication (e.g. from the AuthenticatedRouteMixin).

How to login a Django account from an iOS App?

In my App I need to communicate with my Django website. Some resources require authentication so I need user login.
But this does not happen in a browser or a web view. I need to use Object-C to issue a login request and handle the response - basically to store the session ID I guess.
On the web server side, how should I do this in Django? To have a stand-alone view for that and return JSON maybe? How can I get the newly generated session ID though?
I wouldn't get the session ID. I believe logging in a user is more geared toward a web interface. I would create an API that serves the resources you need in your app. http://en.wikipedia.org/wiki/Representational_state_transfer Authentication would probably be best suited for a private/public key pair or some other similar popular api authentication system.
You don't need to make any changes to your authentication system, save for maybe making sure the login form is usable on the smaller screen. Cookies work the same on iOS as they do on the web. You can display a modal UIWebView with your login form. After the user logs in, presumably you are setting a session cookie. If you make a subsequent request to the domain the cookie matches, the cookie should be sent along. You want to look into the HTTP 'Accept' header field, which specifies the content type the client expects to receive. In your controller (view?), you'll want to check the 'Accept' header, and return the appropriate content type, probably 'application/json' (or a custom type for your API).