How to align client and IdentityServer cookies - cookies

I'm moving an ASP.NET web application away from Forms authentication to OIDC authentication through IdentityServer, with implicit flow for getting an ID token. Forms authentication has options in the client web.config such as 'timeout' and 'slidingExpiration' and I'm looking for a way to make sure the client is just as configurable when using IdentityServer.
I understand there are two separate cookie management systems in this scenario - the client's and IdentityServer's. I would like to align them as much as possible and have a single place for configuring these options. This could be either at either end, one handing responsibility to the other.
One option I've explored is setting UseTokenLifetime = true on both ends and then using the IdentityServer Client property IdentityTokenLifetime as a way to configure timeout for the client. Both cookies should then expire at the same time specified by the IdentityTokenLifetime. When the client's cookie times out it'll redirect to IdentityServer for authentication, where the login prompt will be shown because its own cookie will have expired too. However, I don't think this allows a sliding expiration option?
Another option might be to set UseTokenLifetime back to false, configure cookie options in the client cookie middleware, and ensure the client sends prompt=login when authenticating. This means even if IdentityServer has cookie settings which don't match the client (e.g. the IdentityServer cookie is still valid after client's has expired), it'll still always show the login prompt. The downside to this seems to be that it would inhibit SSO should I add more clients, because they'll always have to login for each client.
I would appreciate any thoughts on this
Thanks

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.

Security of storing Bearer token in cookies

My SPA uses React as front end and laravel API as backend.
When the user logs in (via axios and api), the api returns an access (Bearer token) as response. I use the react-cookie framework to store the access token as cookie in the Browser. This cookie will be read and used for any future request.
Is this the right way to do?
Isn't cookie data just something in the Browser that can be easily obtained by any attacker? Since it is just a file one the computer somewhere.
What is stopping an attacker from grabbing that cookie, impersonate as that user and start performing actions that requires authentication?
The token has a life span of lets say 1 year. It will only be refreshed every time the user logs in. I understand that if I set the life span shorter it will be more secure. However that will mean the user would have to log in constantly?
-----Update-----
Im not sure if any of the provided solution answered my question. A SPA app is front end based and the request can be from anywhere such as Postman, Mobile app, or any third party device that wish to talk to my backed server. So those device needs a way to store some access token locally to be used for any future request.
The only way I know this could happen is for my server to send some auth token to the requester and have it store it somewhere to be used for next request.
In this case, Im not sure if CSRF token or any other means would help my concern?
Just like facebook, if I clear my cache, I will have to re-login. That means facebook is storing something on my location computer so I can be automatically authenticated next time
I just want to add some disadvantages of storing tokens in cookies that you should also be aware of:
The max size of a cookie is only 4kb so that may be problematic if
you have many claims attached to the token.
Cookies can be vulnerable to cross-site request forgery (CSRF or
XSRF) attacks. Using a web app framework’s CSRF protection makes
cookies a secure option for storing a JWT. CSRF can also be partially
prevented by checking the HTTP Referer and Origin header. You can
also set the SameSite=strict cookie flag to prevent CSRF attacks.
Can be difficult to implement if the application requires
cross-domain access. Cookies have additional properties (Domain/Path)
that can be modified to allow you to specify where the cookie is
allowed to be sent.
------- Update -----
You can also use cookies to store the auth token, even it is better (at least in my opinion than using local storage, or some session middleware like Redis). And there are some different ways to control the lifetime of a cookie if we put aside the httpOnly and the secure flags:
Cookies can be destroyed after the browser is closed (session
cookies).
Implement a server-side check (typically done for you by
the web framework in use), and you could implement expiration or sliding window expiration.
Cookies can be persistent (not destroyed
after the browser is closed) with an expiration.
Your JS should not have access to the cookie. There are flags you can set on cookies that will help protect them and make sure they are only used for the correct purposes.
The HttpOnly flag is set on the cookie then JS will not be able to access it but it will still be sent with any request.
The SameSite flag will ensure that the cookie is only sent back to the site that gave it to you. Which prevents leakage.
The Secure flag will make it only send the cookie over a secured connection to prevent someone from sniffing it out of your web traffic.
Edit
You might want to lookup an authorization workflow but the gist of it is this:
User logs in with username and password
A JSON web token is issued upon login from the backend and sent to the browser
The JWT(JSON web token) can be stored in a cookie in the Web Storage(Session Storage) on the browser
Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization
Please see #tpopov answer as he also made some really good points.

jsessionid saved in cookies in wicket can they be used to login again be making them persistent cookies , if so how to do it?

Wicket saves jsessionid (actually tomcat does that) , now can I make those jsessionid cookies as persistent cookies and can I use them to make the user login next time he/she visits my page .
The idea behind 'JSESSIONID' cookie is to track a live user session.
Once this session is expired at the server side, i.e. inside Tomcat, the cookie becomes useless. The browser will send it to the web server and there it will be ignored.
What you ask for is "RememberMe" cookie. This cookie usually brings encrypted information about the user. If the user session is expired then the application will forward you to the login page. During this process the application may check for such RememberMe cookie and use it to auto-login this user without asking for her credentials.
Apache Wicket provides DefaultAuthenticationStrategy with support for RememberMe cookie. See wicket-auth-roles SingInPanel.java and the source code for http://examples6x.wicket.apache.org/authentication3 to see how it works. You could also use Spring Security, Apache Shiro, Stormpath, etc. for the same functionality if you decide so!

Requests to <server>/browserconfig.xml do not send session cookies?

I have little experience with Windows 8 and our organization does not yet support it but some end users have it.
Users running Windows 8.1 and IE 11 have presumably created a live tile referencing our secure application. We are seeing user requests to /browserconfig.xml with no authentication cookies while the user is currently authenticated in IE. Windows appears to not send existing authentication session cookies in the request but is processing response cookies. This is causing the user to become unauthenticated. One user claims to have removed the tile from their desktop but we are still seeing requests to browserconfig.xml from that user. When that user ran IE developer tools and logged network traffic, we see the transition from authenticated to unauthenticated once our authentication cookie value changed. IE did not log the request that changed the cookie. IE did not log the request to browserconfig.xml at all, presumably because it was in a different thread. Our server did log this additional request. The request to browserconfig.xml consistently occurs between the change from authenticated to unauthenticated.
Questions:
Is the request to browserconfig.xml expected to include cookies (both session and not) in the request? If not, why does Windows appear to process response cookies?
The user claimed to have removed the tile. If this is true, is there a difference between hiding and deleting tiles? We are still seeing requests to browserconfig after the user claimed to have removed it. Unfortunately, I cannot confirm the user claim.
You cannot vote on your own post
0
I saw this exact behaviour debugging our web application. I also saw it once in a request for /favicon.ico not sending the authentication cookie (while in the middle of using the site).
In my case, the requests that didn't send an authentication cookie have user-agent header corresponding to "IE11 on 64-bit Windows 8.1 Update", and all other requests have user-agent header corresponding to "IE11 for the desktop on 64-bit Windows 8.1 Update".
My fix was in global.asax.cs Session_Start(), if requesting /browserconfig.xml or /favicon.ico, then don't set any cookies in the response.

Can JMeter cookie manager override cookies set by the application?

I am testing an application that requires a user to authenticate, and then uses a cookie to track the user session. If authentication fails, a cookie is set that identifies the session as belonging to an unidentified user.
Unfortunately, authentication is via Kerberos or NTLM, which cannot be done in JMeter 2.8. My plan is therefore as follows:
Log into website with Internet Explorer.
Copy cookie that identifies session out of IE and into JMeter cookie manager as a user-defined cookie.
Use JMeter to test application
Essentially, this is session hijacking.
What I am observing is that (1) the JMeter cookie manager does not seem to be supplying the cookie to the application in the first request, (2) after the first request the application sends a different cookie back to JMeter, and (3) subsequent requests use the application-defined cookie, not the one I supplied.
So my questions are:
Is the approach described plausible, in theory at least?
Do application-defined cookies always override user-defined cookies?
Why might the cookie manager be not sending my user-defined cookie?
Thanks in advance.
Try using JMeter nightly build, it has been reported recently that it worked with NTLM after upgrade of httpclient libraries.
http://jmeter.apache.org/nightly.html
You approach seems really weird to me and I don't think it will work or even if it does be realistic.