Integrating SSO with an Application with Native Authentication - spring-mvc

I have been tasked with integrating single-sign-on for an existing application, so I've been working on a couple of demos. The first one was the standard demo for Spring Security and I got that working. Now I'm trying to do a proof-of-concept demo where I created a toy version of the application in question with only two screens: one for login, and one to display some information about the user that logged in. I want to integrate SSO with this application so that the user has two ways to be authenticated: either by entering credentials directly in the login screen or by a SSO SAML request...
So I copied over SAML libraries and configurations from the standard SSO demo into my proof-of-concept application, and I seem to have SSO working, albeit a bit too well, in that I'm no longer able to get to my login screen, i.e., I still want that to be the default behaviour for someone entering the base URL for the application. How do I have to configure my application to achieve this?

The way I solved the problem was by changing the Spring Security configuration so that instead of using the generic /** to require SSO authentication for most pages of the application, it nows only requires such authentication for a single HTML page, sso.htm. This "page" is really translated by the application as a request to a controller that handles the application-specific processing for an SSO request. The initial page for the application, redirect.jsp, now contains some logic to pick which page a user should be redirected to, based on whether he or she got to that page directly (i.e., by typing in the default URL for the application) or via a SAML message from a trusted identity provider.
Note: For this to work, the initial page cannot be designated in the Spring Security configuration as either a secured or unsecured page. If it were secured, then this page could only be accessed after an SSO authentication, so a user would be thwarted from doing a non-SSO login. If unsecured, then the security context would not be accessible from that page, so the page logic would be unable to determine if the user in question has SAML credentials and an SSO authentication request for the application could never be fulfilled.
Once the user has been authenticated, either by credentials entered in the login screen or by an SSO request, from that point on, the application's continuing authentication of that user to view its pages is the same, i.e., no further SSO authentication is done. But when the user logs off from the application (or is logged off due to a session timeout), a check is made then to see if SSO authentication was done for this user. If so, then in addition to being logged out from the application, a local SSO logout is also done for the user, i.e., the SSO authentication session for the application is terminated, but the user remains logged in with his or her identity provider. So such a user could log back into the application in question, either directly via the application's login screen or by having the identity provider issue a new SAML message.
Hope this helps someone else...

Related

Sign out from Windows Authenticated ADFS and sign in as different user in form base auth

We are going enhance the authentication and authorization system of our Intranet web app. After having few days reading about ADFS, STS, claim based authentication, asp.net Identity. Still not sure how these things works together.
Most of our intranet web applications are using Windows Integrated Authentication, we uses windows group or AzMan to do role base authorization. We have few applications(Vendor application) use it own user database and form base authentication.
We want to add following features to our web applications.
For Windows Authentication application, we want to let user to Sign Out / Sign in as different user. So when User A using his/her computer to access the application, it will auto logged in (default windows integrated authentication). When he/she do log out, it will redirect to a form to allow to input other user credential.
We want to allow user login to System A using System B username/password.
e.g. For the windows authentication application, we want allow user login to the application using the credential of the Form base application (Vendor application) of via visa
I don't know if ADFS can solve these two problems.
From my understanding, the main purpose of ADFS is to allow access to internal application from Internet, and it require SSL.
Our application all are in Intranet, and we don't want to manage the ssl cert.
But by using ADFS, perhaps I can enable both Windows and Form Authentication on my application, so then let use log out and re-direct him to the login form as which just like he access outside company network. It should solve the problem 1.
For problem 2, what if I can create a custom STS to issue security token by using the user database of the form base authentication appliaction. Then I can use claim based authentication and allow one application can use ADFS and my STS. It should solve my problem 2.
Is my direction correct? or am I complicated the problem?
ADFS will not work without SSL.
Furthermore, all RP have to use SSL.
Internally, users will be logged in seamlessly using WIA. When they logout, they will simply be seamlessly logged in again.
Also ADFS v3.0 and below can only authenticate against AD.
While what you want is possible using ADFS, the question is whether it's a good idea and worth the trouble. It may be more appropriate to ask the user to log out of the machine and log in with a different account so you can stick with Integrated Windows Authentication (IWA). Writing your own security infrastructure is fraught with peril.
If you really feel these are hard requirements and it is worth the trouble, the following may work.
Write an ASP.NET web application based on Katana and enable Integrated Windows Authentication. This will make sure that the first time a completely unauthenticated request comes in, the application will challenge the browser. Subsequent requests will have a WindowsPrincipal populated in the HttpContext.User and Thread.CurrentPrincipal.
Now, write a piece of OWIN middleware that checks if an authentication cookie is present. If the cookie is not present, it checks the Thread.CurrentPrincipal and serializes the claims into a secure cookie.
If the security cookie is present, it overwrites the WindowsPrincipal in Thread.CurrentPrincipal with a new ClaimsPrincipal created from the claims in the cookie.
Now, when a user navigates to the web application the first time, he/she will be logged in automatically using IWA and the cookie will be created. Now, provide a logout action which deletes the authentication cookie and presents the user with a username and password dialog.
In the POST handler for that action, use WIF to talk to the username endpoint in ADFS (using WS-Trust protocol) and try to authenticate the user with the supplied credentials. If successful, use the claims from the returned token to create a new authentication cookie.

Cross-site Windows and Forms authentication

I have an ASP.NET site on a public web server, where users login using forms authentication.
I would like users within certain organisations to be able to login automatically through Windows authentication (bypassing the login page). However, because these clients are on lots of different servers, I can't just build in Windows security to the main site. (I know there are articles on how to mix Windows and Forms security.)
My idea is for each organisation to install a page onto their intranet which redirects to my website and authenticates the user according to their Windows domain and username. Is this possible to achieve securely? How could I go about doing it?
What you have described is almost federated identity.
As well as a page on each site, you will also need a webservice whch will validate a token.
Essentially the flow is:
User comes to your logon page
you redirect them to their company logon page
their company logon page takes their credentials and redirects back to you returning a token
you then call their webservice to validate the token an determine who the user is.
Many public API's use this scheme (facebook being a notable example).
look up oauth and federated identity for more information.

ASP.NET external authentication

I have an asp.net application in which I have used forms authentication.
Now, there is a need that user authentication is done outside of my application.
There will be an intro page which will do needed authentication.
Then, after authentication is successful user should be redirected to my app.
Of course, if user is not authenticated via that external page and tries to access my app directly, I need to redirect him back to this external log in page.
What's the best way to implement such a functionality? One way which I think is feasible is that I transfer some particular encrypted string in cookie from external login page and verify it in my application. So, based on that, I can see if user is authenticated via this external page or not.
Your own suggestion of validating the external site's cookie is how I would implement this functionality as well.
I would simply go with adding a Webservice in the first application that you in your stage can connect to a check if the user is logged in, the only problem with this is that you need to know which user whants access to your site and also to confirm that this is truly that user (So a user cant use other users who are logged in). This info could probably be sent via a cookie.
You probably should no be rolling your own single sign on solution in 2011. Rather, you should look at some emerging standards -- particularly OAuth and OpenID. Getting rolling with them is easy -- check out the OpenID website template on MSDN.
At the end we decided to use SAML 2.0 protocol.
External login page posts SAML complient XML digitally signed with certificate to other application. In this XML authenticated username is transferred. Application which receives this XML verifies digital signature with certificate's public key, and if validation is OK, reads username from XML, applies internal application authorization logic and at the end creates auth. cookie. We will probably add encryption so data protection would be complete.

ASP.NET Form Authentication + NTLM + LDAP

I'm trying to add LDAP support to an existing ASP.NET website that uses Form Authentication. This is not a big problem, I just build a simple login dialog (ordinary HTTP POST), query the LDAP directory and log the user in via Form Authentication ticket.
It would be extremely nice to automatically get the users credentials via NTLM (Integrated Windows Authentication) without the need for a login dialog (like what you get when using ASP.NET Windows Authentication with computers in the same Active Directory). Is there an easy way to do this (keep in mind, I can't use Windows Authentication for my ASP.NET app and the server is not in an Active Directory Domain, I need to be able to query LDAP directory manually)? Or would I have to manually do all the LDAP handshaking / challenge/response thingy?
Thanks for your help,
~ saxx
I do just this on my intranet here. These are the steps I use...
Create a login page (login.aspx seems good) & set the web app up for forms authentication. Set authorisation as deny anonymous. These means any attempt to use your app will cause the user to be redirected to your login page if they don't have a auth ticket.
Now the important step. In IIS, set the app to allow anonymous only. On your login page change this to only be Windows Integrated. Now what happens is when the user is bounced to your login page, IIS forces an NTLM authentication. We now have the users name in the headers.
2nd important step. in the page_load method add:
FormsAuthentication.RedirectFromLoginPage(Request.ServerVariables["Logon_user"], false);
What this does is take the username IIS will always give us and put into a forms auth ticket.
There's of course a certain amount of tidying up you may want to do, perhaps adding a logout feature, or stripping the domain name of the username.
Simon

ASP.NET - Detect if user is authenticated with Active Directory?

We have a SSO solution with ADFS for logging into our web app, we also have standard setup that uses authentication with our database. I want to setup a solution that allows for both. So now I am trying to figure out, is there any way for ASP.NET to detect if a user is authenticated with Active Directory so I could do this on the fly? If user is logged in through AD, send through ADFS, else, show login screen. Any idea?
I also realize that this may not work if they are setup to use forms based authentication only after the ADFS process is started.
Yes... In IIS, enable both integrated authentication, basic, and anonymous. All the real work is done in HTTPModule that are registered in the root Web.config (e.g. in the runtime CONFIG folder). The built-in Authentication HTTPModule will set the user Principle once authenticated if authenticated via integrated credentials. You can add your own to be fired after it. If the IIdentity (e.g. User.Identity) has the IsAuthenticated set to false then you know they were not authenticated and can then redirect them. If it is set to true, you can then replace the IPrinciple with one that contains roles that are germane to your application.

Resources