I have a project with the purpose of exposing multiple web applications over the internet. These applications are build using IIS/DotNet and Apache/Php.
The internet user should log-in in only one place, and then be able to access any aplication.
What are the posible solutions to this scenario? One requirement is that changes to existing applications be minimum and another is to use ActiveDirectory for user management.
I have found so far the following solutions:
use a reverse proxy (COTS product) to publish web applications to the internet, and the proxy should take care of authentication/SSO
using forms authentication and a domain wide cookie; this solutions requires changes to existing applications and manual log in in AD
create a new application using forms authentication and after user enters credentials into this application, use these credentials to send a XMLHttpRequest to another applications (this will log in the user)
use client certificates, so that when a user connects to an applications, his certificate will handle the log in process; this approach has a problem when there is more than one certificate installed in the client browser because the browser will ask the user to choose a certificate (and this will happen for every app)
Related
I have a working c#/dotnet Windows desktop application that does its work by hitting various web services in my web application. When the desktop application starts up, it prompts the user for username / password and then hits my login web service, which returns a session token.
I have a large-org customer with many users. That customer wants to provide authentication / authorization for my combined desktop / web application directly from their domain controller. They want single signon, so my desktop app doesn't prompt their users for usernames and passwords.
How can my desktop application retrieve a usable authentication / authorization token from Windows (maybe from the user's Security Principal object)? How can my web application validate that token so it can trust the desktop application and send it a session token?
(My web application runs in my environment, not in the customer's domain.)
With pure-web-app customers I do this successfully with SAML2 and Active Directory / Federation Services. The SAML2 dance gets my user's browser to POST a request to the customer's AD/FS server, which then POSTs a signed response back to my web app.
But I can't figure out how to do it cleanly from a desktop application. Any wisdom?
You can check this samples in github (by jelledruyts): Modern claims-based identity scenarios for .NET developers
It has samples of authentication and authorization using Azure Active Directory and/or Windows Server Active Directory Federation Services.
I suggest read this article Digital Identity for .NET Applications. It's a little old but is a good overview/review.
Tokens come in many different formats. For today’s .NET applications,
however, three kinds of tokens are most important. They are the
following:
User name/password token—This very simple token contains only two
claims: the name of some subject and that subject’s password.
Kerberos ticket—More complex than a user name/password token, a
ticket includes a subject’s name, the name of the subject’s Windows
domain, and other information. Kerberos tickets that are issued by
Active Directory also include an extension that contains security
identifiers (SIDs) that identify the subject and the groups to which
this subject belongs.
SAML token—The Security Assertion Markup
Language (SAML) is an XML-based language that is owned by the OASIS
multivendor standards group. Unlike the other token types that are
described here, a SAML token doesn’t have a fixed set of claims
defined for it. Instead, this kind of token can contain any claims
that its creator chooses.
As soon as the claims are available, they can be used by Windows, the
application, or both. The most common uses of claims include the
following:
Authenticating the user(...)
Making an authorization decision(...)
Learning about this user(...)
Kind of Authentication:
Domain Based Authentication (eg Kerberos tickets):
A domain-based application accepts only a single token format with a
fixed set of claims. One common example is a Windows application that
accepts only Kerberos tickets. This kind of application is easy to
create, and it works well inside a single Windows domain. The problem
is that this simplistic approach to digital identity is no longer
sufficient for many applications
Claim Based Authentication (eg. SAML tokens):
Unlike a domain-based application, a claims-based application can
potentially accept multiple token formats with varying sets of claims.
The token formats and claim sets that this application accepts are
determined by the application itself.
Identity Technologies
Active Directory (AD) Domain Services (full-featured directory service, token source for Kerbero tickets, etc)
Active Directory Federation Services (ADFS) (support for claims-based applications, token source for SAML tokens
Windows CardSpace
Active Directory Lightweight Directory Services (subset of AD services)
Identity Life-Cycle Manager (ILM) (synchronization between different identity stores)
Windows Authorization Manager (tools for RBAC - role-based access control)
Active Directory Rights-Management Services (RMS)
Because AD Domain Services implements Kerberos, the default token in a
Windows environment is a Kerberos ticket. To use this default, an
ASP.NET application specifies Windows Integrated Authentication, while
a WCF application uses an appropriate binding, such as NetTcpBinding.
In either case, the following figure illustrates how a Windows
application with clients in the same domain might use a Kerberos
ticket and AD Domain Services
First versions of AD FS only support SAML with web clients.
ADFS 1.0, supports only browser clients—a restriction that’s scheduled
to change in the technology’s next release.
Hope it helps.
I should preface this with the fact that I've never done this, so I can't give you exact code, but I can point you in the right direction.
You should be able to do this with ADFS and Windows Integrated Authorization (WIA). In a "pure web app", the browser sends the credentials of the currently-logged-on user during the authorization step. In your case, your desktop app needs to do everything that the browser would normally do. Either way, the setup on the web service side should be exactly the same.
In C# with HttpClient, this is the important part:
var httpClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
});
Then, whenever your httpClient sends a request that is challenged with a 401 response, it will automatically resend the request with the user's Windows credentials. This is exactly what a web browser would do. So use that when you get the token.
You may have to send a user agent string in the request, since ADFS seems to limit WIA to certain agents.
Once you have a token, then use the token in your requests to the web service.
The key is that you're replicating what a browser would do. So if you have trouble setting up what the HTTP requests should look like, then access a GET request in your API from a browser and use the browser's dev tools to inspect exactly what the traffic looks like, and use that information to replicate the same request in your code.
I have a web based application which is used to find information about various assets in a facility. This provides only search capability, no CRUD operations allowed from the application (except for READ). This web application is always kept open in a touchscreen device (ie workstation) and this could be used by any of the facility staff. The user does not want to initiate login and logout for each of the search operation.
We are planning on deploying the web application onto the cloud. Although it is not a need to authenticate the user who is accessing the web-application, it is still a need to ensure that information about assets in the facility are not accessible by others. How do I build this authentication layer? The various options I can think of are:
1. Include userid/password in the URL as parameters. I could create a userid/password for each of the facility. Simple, but userid/password area always visible.
2. Certificate based approach. Certificates are created for each of these workstations and deployed on those workstations. Quite secure, but has the challenge of managing the certs life-cycle. As well challenge of configuring the web-servers with certs from different facilities???
Any suggestions?
Thanks,
Prasanna
A simple, but not secure thing. Do an IP check and if the IP is from your facility then grant access.
The second, but secure method is to do a verification at the start of the application with just a password and store a session , so that you will know that people from your facility are accessing the site..
After some theoretical help on the best approach for allowing a SaaS product to authenticate users against a tenant's internal Active Directory (or other LDAP) server.
The application is hosted, but a requirement exists that tenants can delegate authentication to their existing user management provider such as AD or OpenLDAP etc. Tools such as Microsoft Online's hosted exchange support corporate AD sync.
Assuming the client doesn't want to forward port 389 to their domain controller, what is the best approach for this?
After doing some research and talking to a few system admins who would be managing this, we've settled on an two options, which should satisfy most people. I'll describe them here for those who were also interested in the outcome.
Authentication Service installed in the origanisation's DMZ
If users wish to utilise authentication with an on-premises active directory server they will be required to install an agent in their DMZ and open port 443 to it. Our service will be configured to hit this service to perform authentication.
This service will sit in the DMZ and receive authentication requests from the SaaS application. The service will attempt to bind to active directory with these credentials and return a status to indicate success or failure.
In this instance the application's forms based authentication will not change, and the user will not be aware of the authentication behind the scenes.
OpenId
Similar to the first approach, a service will be installed in the client's DMZ, and port 443 will be opened. This will be an OpenId provider.
The SaaS application will be an OpenId consumer (already is for Facebook, Twitter, Google etc login).
When a user wishes to log in, the OpenId provider will be presented, asking them to enter their user name and password. This login screen would be served from the client's DMZ. The user would never enter their username or password into the SaaS application.
In this instance, the existing forms based authentication is replaced with the OpenId authentication from the service in the client's DNZ.
A third option that we're investigating is Active Directory Federated Services, but this is proprietary to Active Directory. The other two solutions support any LDAP based authentication across the internet.
Perhaps this might help…
This vendor, Stormpath, offers a service providing: user authentication, user account management, with hookups to your customers’ on-premise directories.
What about an LDAPS connection to the customer's user directory? They can firewall this off so that only your servers have access if they're concerned about it being public. Since it's SSL it's secure end to end. All you need from them is the certificate from their issuing CA (if it's not a public one). I struggled to get this working for an internal web project in the DMZ and there's a real lack of any guides online. So I wrote one up when I'd got it working:
http://pcloadletter.co.uk/2011/06/27/active-directory-authentication-using-ldaps/
Your best bet is to implement a SAML authentication for your SaaS application, and then sign up with identity providers like Okta or OneLogin. Once that's done then you can also connect it with ADFS to provide Single Sign On for your web application through Active Directory.
I'm just doing this research myself and this is what I've came across of, will have more updates once implementation is done. Hope this gives you enough keywords to do another google search
My understanding is that there are three possible solutions:
Installing something on the domain controller to capture all user changes (additions, deletions, password changes) and send updates to the remote server. Unfortunately there's no way for the website to know the initial user passwords - only new ones once they are changed.
Provide access for the web server to connect to your domain controller via LDAP/WIF/ADFS. This would probably mean opening incoming ports in the company's firewall to allow a specific IP.
Otherwise, bypass usernames/passwords and use email-based authentication instead. Users would just have to authenticate via email once every 3-6 months for each device.
I have to begin implementing this for an upcoming project and I'm seriously leaning towards option #3 for simplicity.
So a bit of background, I'm working on an existing web application which has a set of users, who are able to log in via a traditional login screen with a user name and password, etc.
Recently we've managed to score a client (who have their own Intranet site), who are wanting to be able to have their users log into their Intranet site, and then have their users click a link on their Intranet which redirects to our application and logs them into it automatically.
I've had two suggestions on how to implement this so far:
Create a URL which takes 2 parameters (which are "username" and "password") and have the Intranet site pass those parameters to us (our connection is via SSL/TLS so it's all encrypted). This would work fine, but it seems a little "hacky", and also means that the logins and passwords have to be the same on both systems (and having to write some kind of web service which can update the passwords for users - which also seems a bit insecure)
Provide a token to the Intranet, so when the client clicks on a link on the Intranet, it sends the token to us, along with the user name (and no password) which means they're authenticated. Again, this sounds a bit hacky as isn't that essentially the same as providing everyone with the same password to log in?
So to summarise, I'm after the following things:
A way for the users who are already authenticated on the Intranet to log into our system without too much messing around, and without using an external system to authenticate, i.e. LDAP / Kerberos
Something which isn't too specific to this client, and can easily be implemented by other Intranets to log in
Both of your suggested options are insecure, even if you use SSL. Never pass credentials on a URL, put them in the HTTP request by using POST.
There is a standard called SAML and this can be used to solve your problem. The challenge is choosing which version to implement. I would choose SAML 2.0.
Google Apps implements a flavor of SAML 2.0 and allow you to authenticate using your intranet credentials. In the case of your application, you would be the service provider and your client would be the identity provider. As long as you implement the standard correctly you should be able to support any new client (identity provider). Here is a list of SAML implementations you might want to take a look at. If you need the client to pass over information in addition to the authentication information then SAML can facilitate this with metadata.
You will still need to implement SSL to encrypt network traffic.
I hate to answer my own question, but I hate even more a question with no answer. In the end we went with a very similar implementation of SalesForce's delegated authentication SSO implementation.
http://wiki.developerforce.com/page/How_to_Implement_Single_Sign-On_with_Force.com
Essentially the solution has a trusted site, known as the delegated authentication authority, who has a list of users who are logged into the company intranet.
When the user logs into the company intranet, and they click a link to our application, the company intranet will pass the user name and a generated token (which expires after a set amount of time) to our application.
Our application will then check if the user name is on our site, and if so, send the username / token (along with the source IP and a few other parameters) to the delegated authentication authority. If all those items match on the delegated authentication authority, it returns true and the user can log in. If it returns false the user is denied access.
We've found this system to work quite well, and even implemented a couple of extra security features like SSL, client side certificates, VPN tunnel, and even restricting the IP addresses which can access the site and the delegated authentication authority.
I know it's bad form to answer your own question but I hope this helps someone else who might be having the same problem ...
Several sites, including this one, are using OpenID to authenticate their users. And of course, OpenID is a good solution to manage user accounts, simply by linking them to their OpenID account.
But are there similar solutions that could be used for desktop applications? I know there's CardSpace, where you create a custom ID card to contain your identity and optionally protect it with a pincode. But are there more alternatives for authentications on a desktop system or on systems within a local intranet environment?
And yes, I can write my own system where I keep a list of usernames and (hashed) passwords and then build my own login system but I just hate to invent my own wheel, especially when I need to keep it secure.
I would recommend that you look into the option of building an STS (using WIF, aka Geneva) and use (active) WS-federation in your windows app. Or if you can wait that long, just use Geneva Server when that is released.
We have a solution that works more or less like this:
Desktop tool prompts the user for ID/password
Desktop tool sends the ID/password over an encrypted (SSL) channel to the server.
Server initiates an HTTP request to a known URL of a login form and inputs the username and password as if they were form fields.
If the HTTP server responds appropriately, the server accepts the client as authenticated.
The target of that HTTP request should be tied to whatever single sign-on system that you use for the web application environment. In our case it happens not to be OpenID but it could be.