I'm playing around with Kerberos SSO. As experimented so far,
When I open a web app that is configured with Kerberos, from the browser, it prompts me for the username and credential, once I enter, I'm logged into the web app .
When I do a kinit from the terminal and give my credentials, I'm signed into the KDC for the given user. After kinit, when I open a web app I'm signed into the web app, without any credentials.
One possible explanation is, when I do a kinit, the TGT is stored in the OS which is available for other clients in the host machine so that my browser was able to use that TGT without prompting me for password.
Now my questions are,
Will I be able to cache the TGT without using kinit?
If yes, how can I do it using a Java client?
If the answer for the first question is yes, will I be able to do it from my web app opened in the browser?
Whenever kinit is executed, a TGT is requested and stored in OS ticket cache.
This TGT can be used to get TGS (service ticket) for multiple services.
If you haven't added your app url as a 'trusted intranet site' in browser, then browser will give you pop-up for the first time for every new session.
Browser accepts the credentials, gets the TGT from your KDC, and puts it in cache. Furthermore, using this TGT, it ask the KDC for the TGS to your app url (usually identified as "HTTP(S)/APP_SERVER_HOSTNAME").
You can verify this-
Perform klist purge to clean all the tickets from cache.
Open browser and hit your app url.
Provide credentials in pop-up and submit.
Execute klist- observe there are two tickets in cache.
One of the ticket is TGT, which spn like - krbtgt#XXX.domain.
The other is TGS for your service - usually "HTTP(S)/APP_SERVER_HOSTNAME".
Please note:
TGT is created by default when you login to the OS. So you can see there's a TGT for your user in OS cache.
OS ticket cache behavior can be platform specific (not verified by me).
You can obtain TGT/TGS or even delegate the credentials using (java)code.
Cache mentioned in your KRB conf is not necessarily the OS ticket cache.
For credential delegation, check out this - Java SPNEGO Authentication & Kerberos Constrained Delegation (KCD) to backend service
Related
We have a client/server based application that is developed internally. Clients and server communicate over a TCP/IP connection with an application-specific protocol. The clients run on Windows and the server runs on Linux. All machines are in the same Active Directory/Kerberos domain/realm.
Currently, the user enters a username and password when they start the application. The server checks the username and password (authentication). Based on the username, the server also determines access to resources (authorization).
We want to add Single Sign-On (SSO) capabilities to the application. That is, we do not want the user to enter a username and password but we want to automatically logon as the current Windows user.
Of course, determining the current Windows user has to be done securely.
I have come up with the following setup:
I use SSPI (Negotiate) on Windows and GSSAPI on Linux.
When the client connects to the server, it uses AcquireCredentialsHandle (Negotiate) to get the credentials of the current Windows user.
The client uses InitializeSecurityContext (Negotiate) to generate a token based on these credentials.
The client sends the token to the server.
The server uses gss_acquire_cred() to get the credentials of the service. These are stored in a .keytab file.
The server receives the token from the client.
The server uses gss_accept_sec_context() to process the token. This call also returns the "source name", that is the current Windows user of the client.
The server uses the "source name" as the username: the server performs no additional authentication. The server still performs authorization.
This works but I do have some questions:
Is this secure? It should not be possible for the client to specify any other username than the Windows user of the client process. If a user has the credentials to create a process as another user (either legally or illegally) than this is allowed.
Should I perform additional checks to verify the username?
Are there alternative ways to achieve SSO in this setup? What are their pros and cons?
What you've described here is the correct way to authenticate the user. You should not have to worry about the user specifying a different name; that's what Kerberos takes care of for you.
If the client is able to obtain a service ticket, then they must have been able to authenticate against the KDC (Active Directory). The KDC creates a service ticket that includes the user's name, and encrypts it with the service's secret key.
The client would not be able to create a ticket for the server with a fake name, because it doesn't have the necessary key to encrypt the ticket.
Of course, this all assumes that you've set everything up correctly; the client should not have access to the service's keytab file for example, and the service should not have any principals in its key tab except its own.
There's a pretty detailed explanation of how it works here.
I have a client application (windows) which the user is logged into. From this application, the user will want to access a remote website using single sign-on (SAML) and will be authenticated by Microsoft WIF. To do this the user, will click a button which opens a local web browser, generates a SAML token (containing username and roles, etc) and makes a HTTP POST to a remote website to access it, signing them in.
I want the user to be signed-in automatically, based on their credentials from the windows application.
I know roughly how to generate the SAML token, but presume this requires the signing certificate to be installed on the local PC, which would need to be installed into all PCs in my Company.
Installing this certificate doesn't seem quite right. How else can I safely allow users to generate a SAML token which will be accepted by the Service Provider (via single sign-on)?
UPDATE:
The user is not authenticated into the Windows Application using Windows Authentication (Kerberos), we make a custom SQL call to a database of username/password.
In the win app, we will know the username and their roles, so could generate claims from this, or pass it to a remote STS to generate and sign the SAML token. But again passing this data across to the STS seems totally wrong again.
The signing certificate must not be on the user desktop. Otherwise, any user could potentially generate a SAML token with the userid it wants.
What you want is a Secure Token Service (STS): an identity provider that will authenticate your user through Kerberos (as you want to re-use the identity of the logged-on user) and give you a signed SAML token.
All of this could be done when you open a web view in your application. The starting url should be the Identity Provider endpoint for IDP-initiated SSO, with a url parameter identifying the service you want to access.
i have a weird thing going on. I have configured a website to use windows authentication. Now when i check on a client in a domain or on my domain controller i can access the website after entering my credentials. But on the webserver itself i can't login with these same credentials. Is this normal behaviour or what can cause this to happen ?
I just read the article here: http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/single-sign-on
I have just finished building an app that can authenticate users via WAAD, or via a local installation of ADFS on their corporate network (configuration point allows them to select one or the other).
The app will be hosted in Azure. Can someone tell me if it is possible for users who are on their corporate network to login to this Azure app WITHOUT entering their credentials?
Here is the flow:
user navigates to the cloud app
FAM detects they aren't authenticated, and redirects the browser to their ADFS server on the corporate network
ADFS server replies with 401 challenge (I assume this is what's happening)
user sees a user name/password box, and enters in credentials
user is redirected back to the cloud app with a token containing their claims
I don't understand why #4 is required if the user is already on their corporate network. Shouldn't ADFS use Windows Authentication here so they don't have to enter their password? Is there a way to configure ADFS to do this?
Thank you!
This can be accomplished by adding the Url of the ADFS endpoint to the local intranet or trusted sites of Internet Explorer. By default Internet Explorer will pass in the Windows credentials to sites in those two groups. If that doesn't work, you would have to double check that setting hasn't been modified.
I use Java Web Start. The file is on http server, that needs name and password (it's windows server). What the Java Web start does is this (with user and IP redacted):
The same on MS Windows client. There is this "Save this password in your password list" option, that does nothing at all (on both Mac OS and Windows), when running this java web start app again, it wants the password again.
Is it a bug in JWS? Or what is going on exactly?
I just had the same problem.
turns out you need to restart your web browser to have the java remember your password.
I also allowed that java cache, but i dont think that was the solution.
I've implemented a workaround for this problem. You can use some kind of cookie based authentication for supporting password authentication.
In my case when a successfull login happens using the HTTP basic authentication i send a cookie in my servlet which holds the username and password the same way the HTTP header contains it when Basic method is used (BASE64 encoded). Web Start stores this cookie in Internet Explorer's cookie store on Windows (on other systems Web Start has it's own cookie store). Web Start then sends this cookie everytime a resource is being accessed from my domain. You can specify a very long lifetime for the cookie (like 10 years) which will probably outlasts the current OS installation anyway.
On subsequent requests i check for the present of the cookie and try to validate the user according to that. If the Cookie auth is invalid and no HTTP Authorization header received (or that's invalid also) i'm sending the HTTP 401 Unauthorized status.
The disadvantage is that username and password is being stored as a cookie on the computer. The password is being sent through the network the same way as with HTTP Basic authentication just in a different header so you can protect it with HTTPS.
This also solves the lack of password remembering option on Linux Web Start.
I implemented the cookie idea, the trouble is now, how do you clear the cookie, if you want to? I mean, nice that the cookie is persistent, but what if the user wants to clear the cookie? As far as I see, the Java console has no option to do it. Clearing the web start cache doesn't seem to do it. On Windows, supposedly IE stores it, so IE gives an interface (haven't tested it myself). But on Mac and presumably Linux, I just can't find out where they are stored. Tried looking in preferences files, and tried blowing away the whole Java cache folder, but they are still stored somewhere. Anyone have an idea?