Login redirect to custom domain other than the one which requested - identityserver3

I have a unique scenario where my users come from myapp.com, then they would be redirected to idsvr login and we have a custom field for entering district code and then after they login they need to be redirected to districtcode.myapp.com. Users will not be going directly to districtcode.myapp.com, so they don't actually come from that domain. So can I use idsvr for this scenario.
The only way that I can think of is after they login send them back to myapp.com where they came from with districtcode as a claim and redirect them back to districtcode.myapp.com and also register districtcode.myapp.com as a valid redirecturi?
Is this the way I have to go with? or is there any other approach that I can take?
Thank you for your time.

Yes - you need a "district code neutral" redirect URI to go back to.
If you can set a domain for "districtcode.myapp.com" from "myapp.com" - then you could do the signin centrally - otherwise you need to go back to idsrv for another round.

Related

IdentityServer3 - Contacting IdP after user is authenticated

We have SPA, IdSvr3, and a third party IdP(AAD B2C).
The user authenticates successfully. When the user clicks an edit profile link in the SPA, they are directed to IdSvr using the authorization_endpoint. I pass in an acr_value called "profile."
I believe this is the same problem as this gentleman- https://github.com/IdentityServer/IdentityServer3/issues/2816#issuecomment-217161898
I've tried a few things:
Implemented ICustomRequestValidator.ValidateAuthorizeRequestAsync.- In this method, I retrieve the acr_values. There doesn't appear to be a good way to direct the user from here. There is the RedirectUrl on the ValidatedAuthorizeRequest that does redirect the user, but all the information on that object is from the client request to IdSvr and is not relevant to the IdP.
Perhaps there is a setting on the ValidatedRequest that could be tweaked to force IdSvr to direct over to the identity provider(in this case the IdP is - Microsoft.Owin.Security.OpenIdConnect.OpenIdConnectAuthentication)
Implemented a UserService. If the user is logged in, the events trigger IsActiveAsync and GetProfileDataAsync. In IsActiveAsync I can get the acr value from the HTTP context, and set IsActive to false, forcing IdSvr to go back to the IdP. I can't access the context from OpenIdConnectAuthenticationNotifications.RedirectToIdentityProvider, so I haven't found a way to access the acr value there. Is there a way to pass something into here to check if this should be an edit profile?
Similar to the UserService I've implemented IsAuthenticationSessionValidAsync to invalidate the session and force the idsvr to direct to the Idp. This has the same issue of not being able to access the acr value.
PartialLogin doesn't appear to be the right strategy for this either because it appears to only be triggered from a user who isn't authenticated yet. Perhaps if we force the user to log-out, this could be used to direct them to the IdP? https://identityserver.github.io/Documentation/docsv2/advanced/userService.html
Logging the user out feels like the wrong approach to begin with, but it seems like it could be made to work.
Is there a standard way of intercepting a request and directing it over to the IdP based on something in the request?

Identity Server 3 - Silent sign-in / sign in without login page. Including single sign on

I have come across a number of articles that discuss a similar matter but I cannot find a definitive answer.
My company would like to begin using Identity Server 3, however one of the requirements is to be able to authenticate an external user without them having to manually enter their credentials.
This must be capable of providing single sign on capabilities also as we have 3 different systems and our users should only have to sign in once.
Essentially, the external user has their own CRM.
The CRM holds their username and password for our software.
They then click a button in their CRM to launch our application
This redirects them to our website with a payload containing their credentials
We call a web service to authenticate the user
It is fundamental that we do not change this process for our partners.
Can I implement a custom service provider to provide the authentication or is there some other way of achieving this? If so, could you point me in the right direction for how this can be done?
Many thanks
Craig
I would assume that you'd create a mechanism for their CRM to get a token at the time the client logs into their site and then have them send that token via url to your callback page. This would use the machine-to-machine type grant, or the client-credentials flow. Then that page could validate the token and log the user in. There would have to be some sort of unique identifier between the two systems like email or something. Just an idea.

Login to a website from iphone application

I am working on iPhone application which have login form to access application functionality same as website. now i want to add one button in iphone application that redirects user in to website in safari browser with successfully login.
After success login in to iPhone application, user want to check website in browser so i just need to add functionality that user can directly login in his account and redirect on particular page.
i have some basic idea for that we can do with encrypted username and password with url.
like http://xyz.com/login/username=abc&password=abc
but i know that its not secure way to pass username and password with url.
So please suggest me any other way if possible.
Any idea or alternative that how to implement this.
Thanks in advance.
There are a few ways to do it.
Any time you send password information over the Internet you want it to be encrypted over SSL. This will require an SSL Certificate for your web server though and it's not always possible.
You can also encrypt the username and password yourself in a way that only your web server will know how to decrypt. So the username "foo" could be turned into "oof" and the password "bar" could be turned into "rab". That way if someone intercepted your requests, they couldn't know what the username and password were without knowing how you changed them.
Why not pass the session id?
Here's what I mean: When you log in to a web site, typically you're assigned (or already have) a "session cookie" which essentially tells the server "This visitor has session ID 'XYZ'", and allows it to retrieve the server side information stored for that user (like who they are, that they authenticated, or whatever else you store in the session store.
One of the easier ways of moving to/from applications is to make sure that all logins generate a server side session, and provide a script which will overwrite the user's session cookie and redirect them to the proper page.
session_restore.php?sessionId=12345&redirect=HOME
The doubters here will argue that providing such a script is tenement to a security breach, but I would argue that all of this information is stored client side already, and can be accomplished without the server's intervention anyway. (session hijacking plugins for popular web sites exist for firefox that will grab session IDs from wireless networks - no technical skill needed)
Doing it this way just makes the process friendlier to the user, and if your site provides SSH access (which you really should be doing anyway) then the risk is very minimal.

How to make a specific web page inaccessible, except to those who get there by a redirect

I have a webpage on a Joomla based website that I am trying to make inaccessible to anyone but those who have been redirected there through a redirect page.
Basically, they would purchase something on a form on my page which is integrated with Paypal, and when Paypal payment is complete I have them redirected to this specific page. I don't want anyone to be able to just copy this url and be able to come back to the page later. Is there a way to do this?
Then you have to store some "token" in your database, which is invalidated after the first time a returning client accesses your "thank you" page.
The token should be given to the client (in the URL) when you redirect him to Paypal and when he comes back after a valid payment, the token must still be in URL.
As far as I remember from the time I tried to use PayPal in one of my projects, it is possible to pass something like this to Paypal and get it back.
Checking a redirect is a poor way to do this. Such things can be easily spoofed. Instead have the pages you require a redirect from to create a session record of some kind and pass the ID of that record in the query string to the restricted page. The restricted page can deny if the session ID does not exist in the database or is too old.
It's been a while since I worked with Joomla. You might be able to look at the Server variables and check the Referring URL. If it's not one of your web pages or paypal, then you can redirect the user to the page of your choice.
I would include a specific token on the redirect. Maybe a Guid that has a limited life and is assigned to that specific user.
Paypal has a feature called Express Checkout that does just what you're looking for.
If you only care that the link expires shortly after it is used, then I think you should create a one-time URL for the content you are trying to protect. Have the action of purchasing create a unique key or token, store the value of the token on your server, and then reference that token in your link:
example.com/purchased_content?token=59803475203658902345089
When the link is clicked, check against your stored values. You can expire them based on whatever criteria you want.
If you also want to prevent copying the URL to somewhere else, you can have the action of purchasing set a cookie with the token value. Then check the cookie when the link is clicked. This is not foolproof since a knowledgeable user can copy the cookie too.

Cookie based SSO

How can I implement a cookie based single sign on without a sso server?
I would to share the user logged in across multiple applications using
only a cookie on the browser.
In my mind it's working like this:
user logs in an application
the application verifies the credentials and then it setting up a cookie on
the browser storing the username (that could be coded with a private key)
if the user opens another application, it searches the cookie and reads
the username on the value (using the key for decode the string)
In this solution a user may see the browser cookie (of a another user)
and take the string codified of the username. Then he could adding it on
an own cookie (no good!).
There's some secure way to do this? With a timestamp based control or
something like this?
Thanks in advance.
Bye
P.S.
I know that my english isn't very well.. sorry for this!
This is impossible. Cookies are unique to each domain, and one domain cannot read another domain's cookies.
I think the answer comes a little late, but maybe I can help someone.
You can have a cookie / localStorage in an intermediate domain connected to the home page using an iframe
1) Login
The login form in any of your domains deposits the identification token in a cookie on sso.domain.com by an event (postMessage)
2) Verification
domain1 and domain2 include a iframe pointing to sso.domain.com, which reads the token and notifies the home page
To simplify development, we have released recently a cross domain SSO with JWT at https://github.com/Aralink/ssojwt
There is a simple solution without using an sso server, but not with 1 common cookie, as we know that cookie's are not shared between domains.
When the user authenticates on site-a.com, you set a cookie on site-a.com domain. Then on site-b.com, you link a dynamic javascript from site-a.com, generated by server side script (php, etc) who has access to the created cookie, and then copy the same cookie on site-b.com on the client-side using js. Now both sites have the same cookie, without the need of asking the user to re-login.
You may encrypt/encode the cookie value using a method that both site-a and site-b knows how to decode, so that site-b will be able to validate his cookie copy. Use a common shared secret that without it will be impossible to encode or decode.
You see that on the 1st page load of site-b.com, the cookie is not present, therefore if you see necessary, you may want to do a page reload after setting the cookie.
I have done something similar. There is a PHP application where the user logs in, the system contact a web service and then the service checks the user's credentials on the Active Directory. When the user is authenticated, his PHP session is stored in the DB. Another web application can read the PHP session from the cookies and uery a web service in the PHP applicaiton, the PHP application check the session in the database and return the user id. In this way I have a SSO using SOA.
Do not rely on the user id stored in the browser, is a security error, at least encrypt the id.
The best solution would be to put the login form and session storage in the same application, then this application can provide services to other applications.
And use HTTPS for the kind of infomation exchange.
The cookies can be read only if the belongs to the same domain, for instance:
intranet.example.com
crm.example.com
example.com/erp
You can access cookies across subdomains, but I do not think using browser cookies is a great solution. You really don't need a "SSO server" to implement a single sign-on. It is fairly easy to come up with a payload that both applications recognize. I have seen custom SSO solutions that transmit the payload using XML over HTTPS.
Here is a solution (which will hopefully get heavily scrutinized by security gurus on here):
Have each domain store user data in a similar cookie, and when a user want to jump from one domain to another without authenticating themselves on the new domain, provide a "jumplink" with an encrypted token in the query string. The new domain would decrypt the cookie, and figure out who the user is, then issue them a new cookie for that domain. You would want the "jumplink" to have a very short expiration date, so I would not generate them right into the page, but generate links to a "jumplink" generator and re-director.
This might not be necessary, but the receiving page for the "jumplink" could make a web service call back to the originating domain, to verify the authenticity of the encrypted token and the whether it's expired.
I think this solution would be susceptible to man-in-the-middle attacks (not sure if it would be more so than other auth mechanisms which are currently popular), but you could incorporate a client MAC address and IP address into the encrypted token for extra security.