Share session across subdomains with multiple domains - session

I have 2 Asp.Net Core 2.2 applications and I want to share session between them.
I've set up session in a SQL database and both connect ok.
They are on different sub domains.
I understand that I can set the Cookie.Domain the startup file, which would solve the problem at a basic level, so each application would create the cookie such that it can be accessed.
e.g.
Domain 1. "www.website.com"
Domain 2. "dashboard.website.com"
At present these sites can't access each others session cookie.
If I set the domain cookie to ".website.com", both should be able to access this.
The problem is that we have multiple domains that use this website, so it could be:
www.domain1.com
dashboard.domain1.com
www.domain2.com
dashboard.domain2.com
www.domain3.com
dashboard.domain3.com
I need to be able to inject the current host name into the startup cookie domain, in order to have it dynamically set, depending on the domain of the active website.
Is this at all possible?
Thanks in advance,
David

No, it's not possible. Cookies are domain-bound. You can set a wildcard for the subdomain portion on the cookie, which would then allow it to be seen by example.com, www.example.com, foo.example.com, etc. but you can cannot share with an entirely different domain altogether, such as example2.com.
Your only option in this case is an Identity provider like IdentityServer, Auth0, Azure AD, etc. The way these work is that the auth cookie is set at the provider, and then each individual app is authorized against that provider. As such, they can receive the user principal from the provider, without having the actual auth cookie or their own login functionality.
UPDATE
If you just need to share between sites on the same primary domain, then follow the instructions in the docs. That's focused on auth cookies. If you need to share sessions as well, the same procedure applies, but you must additionally have a true distributed cache setup (Redis, SQL Server, etc.). There's a distributed memory cache, but that's just a default implementation, and it's not actually distributed.

Related

How can I share cookies between two subdomains of herokuapp.com?

I am currently trying to host a website as an experiment on Heroku, I deployed the back end which you can consider yyyy.herokuapp.com and the front end with you can consider xxxx.herokuapp.com,
Now, here's the issue, I need to set cookies between xxxx and yyyy, I know this will be a massive security issue but since this is an experimental website I am not willing to get a custom domain, I tried to set the cookies' domain to: herokuapp.com, .herokuapp.com, *.herokuapp.com, xxxx.herokuapp.com, yyyy.herokuapp.com.
Yet it doesn't work, chrome denies the cookies and gives this message:
This attempt to set a cookie via a Set-Cookie header was blocked because its Domain attribute was invalid with regards to the current host url.
So, how do I approach this issue without the need for a custom domain?
this is my configuration to set cookies (on the back end which uses flask)
response.set_cookie("example_cookie", value="cookie value",
max_age=900, expires=datetime.datetime.utcnow() +
datetime.timedelta(seconds=900), secure=True, domain=".herokuapp.com",
samesite='none')
If herokuapp.com were not a public suffix (a.k.a. an effective top-level domain or eTLD), then in the case of a cookie set by xxxx.herokuapp.com with Domain=herokuapp.com, browsers would send that cookie to yyyy.herokuapp.com
However, there is a snag: in order to isolate its different tenants, Heroku required herokuapp.com be added to the public-suffix list a while back. Most browsers refuse to set a cookie for a public suffix:
For security reasons, many user agents are configured to reject Domain attributes that correspond to “public suffixes”. For example, some user agents will reject Domain attributes of “com” or “co.uk”.
Therefore, attempts to set a cookie with Domain=herokuapp.com will be rejected by browsers, as you've experienced.
Note: adding a leading dot in the Domain attribute of the Set-Cookie HTTP header has no effect, at least in modern browsers.
To get out of this difficulty, you could simply buy a cheap domain name (say infinityvive.com) to serve both your frontend and backend from subdomains of it. Then you'd be able to use Domain=infinityvive.com because your domain would not be a public suffix.

Host name issue with WSFederated Authentication

I have configured Local STS with my web application (which is hosted in IIS 7 and has the host name as www.abc.com) and it can receive the claims from the STS and it can login. Now I have added another host name (www.xyz.com) to my web application. If user a login to a page in the application using www.abc.com/page1 and it redirects to local STS and it authenticates the user and adds the security token. Now if the user visits www.xyz.com/page2 it also redirects to the STS for authentication.
If a user either logged in www.abc.com or www.xyz.com they need to access the other domain page with out login. Is it possible? How do we achieve this?
In broad strokes, if you have two different relying parties, each needs to route the user to the IDP. If the IDP is configured for single sign on, the user will only notice the routing to the IDP the first time. On the second routing, (assuming same browser session and that the routing is within the lifetime supported by the IDP) the user will be authenticated without seeing a page at the IDP and being required to present credentials.
So, part of your answer hinges around what you mean by login: if you mean "experience a challenge and enter credentials" by log in, you should be able to enable this by simply ensuring that the IDP is configured for single sign on.
On the other hand, if by login you mean the redirect to the IDP, then you need to make sure the application is able to share state across the different page names. Note that usual management of state is via cookies, and note that a cookie for abc.com will not be returned to a web page named xyz.com. There are a number of clever ways to resolve this, although i am not aware of any simple application configuration solutions. One example is to have some part of both the abc.com page and the xyz.com page accessed by the url shared.com. State cookies can then be set by the shared.com transaction when logging into abc.com and read by the shared.com transaction when subsequently accessing xyz.com.
I've never had to implement such a cross domain cookie solution and have only had off-hand conversations with colleagues about it: we've always found the silent redirect of single sign on to meet our requirements. Careful research into the privacy impact of such a solution and the likelihood that such cookies might be blocked should be considered before development.

Can SiteMinder inspect cookies and allow/deny access

Is it possible for SiteMinder to inspect a cookie (not the SM_) set by my application, for a value and if it matches a particular value, allow access to a resource?
For example, if my application sets a cookie back to the client with FOO="kjfkjafbf3nd" is there a way on subsequent requests (with that cookie submitted back to the server) for SiteMinder to see it and do something with it, like compare it against a value, or part of the resource URI, etc and perform an action (allow or deny access)?
I am not sure that is possible, in any case this does not seem like a good idea. Since SiteMinder is the first line of protection it should not need to depend on the applications behind it for decisions.
If your application has some authorisation logic and you would like to use that through SiteMinder the correct way would be to use SiteMinder authorisation. You could look at using a different Az directory or use the ActiveExpressions/Active Rules etc.

Use Sinatra session variables across multiple domain names?

I'm building a Sinatra app which needs to use a session variable for one very specific thing. The session variable is set when the user is looking at an SSL enabled page.
I'm using Heroku's piggyback SSL, so the SSL url is something like https://myapp.heroku.com
However, the app itself is hosted at my url, myapp.com
Is there a way to make my session variable, which is set while on the ssl / heroku domain name, available to my app while while on my domain name?
Unfortunately no, since the cookie is tied to the domain. What you'll have to do is either allow authenticated users to use the https://foo.heroku.com domain, and reserve your nice domain for the landing page & other unauthenticated pages.
That, or pay $20 for heroku's SSL add-on.
(I ran into this exact problem in http://appkickstand.com and I chose to just deal with the heroku url for logged in users)
You should look for cross-domain cookies manuals, check this.
But i don't see many reason in setting cookie through secured channel and transmitting it later via raw HTTP, where everyone could sniff it.

How to design authentication and authorization system for REST backend / Ajax front End Application

I am starting a new project where we are planing to build a restful back end and an AJAX font end. I am approaching the problem by focusing on Identifying all the resources that I have and what the various HTTP verbs will do them, their URI and the JSON representations of those resources.
I am looking for the best design for securing the backend. Here is the list of designs I have considered. I am looking for alternative designs not listed below, and pros, cons recommendations. The system will be implemented with Spring 3.0 and possibly Spring Security 3.0, SSL will be used for many parts of the system but not for all of them, so some requests may come on SSL and some might not.
Option 1: Use the HTTP session
Show a standard login screen, create a server side session and let tomcat send back a jsessionid cookie and have the ajax client include the JSESSIONID cookie on every XHR request. This options just feels like it's the wrong approach for the following reasons.
The connection becomes statefull which is against the rules of REST
I want to be able to split the bakcend into multiple seperate WAR files which means i could have multiple HTTP sessions on the backend, if that is the case then this approach does not work. While I don't need the ability to split the backend into multiple apps today, I would prefer a design that allows for that possibility.
Option 2: Find an open source Java based security library that does this
Other than Spring security I have not found any other Java libraries, any recommendations are highly appreciated.
Option 3: Try to use an existing protocol like OAuth
In my very brief look at OAuth it seems that it is designed for authentication across sites where each site has it's own user database. In this system i want a global user database shared across all the backend ajax services.
Option 4: Use SAML and Shiboleth
This options seems over kill and hugely complex to setup and maintain.
Option 5: Send the username and password with every request
This requires that user sends their username and password with every request, which means that the front end AJAX app must store the username and password as a JavaScript object and if the user navigates away from the page then back the username/password combo will be gone and the user might be forced to log in again. I don't want the front end to try and put the username and password into cookie as that would comprise security.
Option 6: Implement my own authentication / Authorization protocol
Create a REST service that users can present their username/password combination to and then get back and security token, which they must send back to the service with every request. The security token would be digitally signed by the service and would have an expiry time. The token would be only good for most operations high security operations would require a new login screen as port of confirming the operation.
Problem with this approach is I have to invent yet another security protocol which seems like a total waste of time.
I am sure I am not the only person up against this problem, I hope the stack overflow community can point to some options and tools that I have not found yet.
Take a look at Apache Shiro. It is an authentication system that has a session management feature that can be used to share sessions across applications. This may be the easiest thing to do.
Or you could use Spring Security (or Shiro) with a Remember Me cookie that is shared across the webapps (as long as they are in the same HTTP domain). The remember me cookie would be analogous to your token in option 6. You can set the expiration on the cookie that so it is short lived like a session cookie or long lived like a regular remember me.
You might also want to take a look at Jasig CAS - Single Sign-On for the Web. It has a REST API and a protocol (Proxy Tickets) that allows services to proxy user AuthN to backend services like you described in option 6. http://www.jasig.org/cas
Briefly...the application that serves up the AJAX client is protected with Spring Security (supports CAS out of the box) and gets a Proxy Granting Ticket that you embed in the AJAX client. The AJAX client uses the PGT to get Proxy Tickets for your REST services...protected with Spring Security too. The REST services get an authenticated userId without every touching primary credentials.
Alternative, you could keep the PGT on the server and use AJAX calls to retrieve Proxy Tickets that are then used by the AJAX client to call you REST services.
As I understood you are going to secure a rest application, to preface you must know that a security provider consisd of three concepts (3A):
-Authentication
-Authorization
-Auditing
to implement these three together you must provide bunch of tools such as :
-SSO provider
-Session Store
-Open Id pattern
-user credentials integration
....
I have used ACL(Spring ACL) to provide authorization services and oauth2 for authentication.
there is one channel to connect these two together and its scopes(oauth2 scopes) but the problem is scopes are not flexible(pure strings) enough to implement authorization modules such as role_voter, cache_strategy, black_list or,Role_base strategy, exceptional permissions, white_list... (but you can use #EnableGlobalMethodSecurity)
In my case I used authorization server as a resource for oauth2 authentication server(take a look at http://projects.spring.io/spring-security-oauth/docs/oauth2.html), then I considered two spots to check authorization, the first I issued ACL to front-end and forced programmer to design her page dynamically up to ACL concept, the second is in back-end on service layer(BLL) using Aspect when one rest is going to be called. I sent the service key as an actee to check if current user has enough access control to do that. and for auditing you must monitor all requests I mean you must use an listener in your gateway or broker...

Resources