How to use Kerberos ticket in two Java applications? - authentication

I hope I will be clear here:
Let's a user authenticates to application A using Kerberos (the code uses the JAAS Krb5LoginModule).
The client now needs to authenticate to Application B as well.
The Kerberos ticket is still valid.
How can I use I make sure that auhtentication flow to application B will not try to create a new Kerberos ticket?
When I use JAAS I perform:
loginContext.login (I of course passed a callback handler to provider credentials and the name that is used as an index to the configuration, see javadoc here), and of course Application A and application B run as different as different processes, so the loginContext object is not shared between them.
How can I reuse the valid kerberos ticket between the two applications which run in different processes, but the user uses the same credentials (same user#realm)
Thanks

If both applications are on the same physical/logical machine, share the same SPN and both are running under the machine account, yes you can reuse the service ticket until it expires. But those is actually handled by the browser. You will never mess with them anyway. Your SPNEGO acceptor does everything for you.

Related

OpenAM + two LDAP servers

I'm a newbie in the LDAP + Liferay + OpenAM world, so I wonder if someone could point me in the right direction in a problem I have. In a real life environment, there are 2 LDAP servers, a OpenAM server and a Liferay application. What the customer needs is to authenticate users in Liferay against OpenAM, and OpenAM should use the LDAP servers. Problem is, the user exists only in one of the LDAP servers (it will be moved from one to the other in one point of the future). What the customer wants is:
Users must be able to authenticate independently of what LDAP contains the user.
The obtained token must be valid for both LDAP servers, as it will be used in a different service (I have no control over it) against only one of them to validate authentication.
As I said, I'm new to this world so, if the answer is too complex (I'm afraid it will be for me), maybe you could point me to books or docs that could resolve this scenario.
Thanks
You should configure LifeRay to use OpenAM for all authentications and you can configure OpenAM to use both LDAP servers (use different realms).
Details for OpenAM configuration will be in the OpenAM documentation.
As the previous answer states you should route all your authentication requests to the OpenAM server and let it validate the credentials against the right LDAP server. Using two different realms (one for each LDAP server) won't work in your case since that will require LifeRay to know where to find the user before hand. Also, sessions are linked to a specific realm.
There are multiple solutions to your problem. Here are just a couple:
Option 1
If you have control over the authentication flow. That is, if your application uses a custom UI and communicates with OpenAM via REST, you could create two different authentication module instances under a single realm (let's say two instances of the DataStore authentication module) each one pointing to a different LDAP server.
Let's call this module instances DataStore1 and DataStore2. Your application can collect the user credentials (username and password) and submit them to DataStore1. If authentication succeeds the user is already logged in. If it fails, the application can try with DataStore2.
Of course this is not ideal since you'll be making two authentication requests per login instead of just one.
Option 2
A better option (though more complicated to implement) would be creating a custom authentication module. This module can try authenticating the user against LDAP Server 1 and then try with LDAP Server 2 if the first authentication failed. Notice that with this option you don't need custom logic on the application side since it will only send a single authentication request to the OpenAM server. In fact, you can protect your application with an OpenAM Policy Agent.
Another advantage of this approach over Option 1 is that you can migrate your users behind the scenes assuming that the end goal is to migrate users from LDAP Server 1 to LDAP Server 2. If the first authentication succeeds your custom code could read the user entry from LDAP Server 1 and copy it over to LDAP Server 2.
Hope this helps you solve the problem.

single sign on java and active directories

We have number of intranets sites, hosted in web logic server, each have its own authentication framework. Now we have a new requests to implement the single sign on. There is another team who are communicating with active directories [pass the domain name and username like phillip_r and it will return the primary email etc], how do I utilize , I read few article about CAS, Kerbos etc and now I more confused do I need to implement them in my case or not, please help me on this, as I don't know where to start.
WebLogic is not 'kerberized' so you can not actual use Kerberos. However you can use WebLogic's SPNEGO handler to provide 'auto-login' from user perspective this is like 'single-sign on' but actually it's only 'auto-login'. The Kerberos token provided via SPNEGO typically has 'userpricipalname#REALM' ... that can be email address, but most of the time it's not email. It will not return arbitrary attributes from AD... you have to do this own your own (e.g. via LDAP).
However Kerberos via HTTP (SPNEGO) only works for enterprise clients, which can directly communicate with the Key Distribution Center (AD KDC).
CAS or OpenAM (http://openam.forgerock.org) are web-based, java-based single sign on systems which offer different means for authentication.
As long as all apps are on Weblogic and all users are in AD domain, you can use Kerberos SSO for all of them with no problem and don't need CAS. Set it up using instructions from Oracle.

SSO / Authentication Server

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)

Pattern for WCF Kerberos Clients where Server uses User Account

We have a WCF (Windows Communication Foundation) client and service application. We're using Windows Authentication with Kerberos.
The issue is that the service may be run under one of many accounts (maybe Network Service, maybe a specific user account -- depends on the IT group). This account is not not likely to change daily, but possibly on occassion (every few months maybe). Additionally, we deliver this client/service package to several groups, and each group may have its own account that they use to run the service on (this is to just let you know that we can't do a custom solution for a single team).
Now the reason the above paragraph is an issue is apparently if the service is not running in the SYSTEM or NETWORK SERVICE account, i.e., a user account, then the client must specify the name of the user account in the identity of its endpoint.
For more on this restriction see: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/feb6bc31-9a4b-4f8d-a887-ef6d2c7abe41
and http://www.vistax64.com/indigo/146204-using-localhost-v-s-environment-machinename.html
Now this seemingly makes it tough to deal with the situation where the IT department changes the account that the service runs on. What is the pattern for handling this, if there is one? How have other people handled this? One solution I've thought of is that the admin sends out an email when the user account of the service has changed, which has a weblink to an application that updates the client or a config file, so the client refers to the new user account. But that seems hackish.
Admittedly, this is a lot like the URI of the endpoint moving. Except, I think there's a lot more expectation on behalf of people that changing the URI is something the client should have to know about, but changing the account the service is running on is something that should be relatively transparent to the client.
BTW, this is required to be hosted on IIS 7.0, if that matters.
I think you can set NegotiateServiceCredential property to True so your binding uses SPNego instead of hard-cold Kerberos. When is set to true, the client does not need to specify the SPN and it can connect to a server running a non-machine account.
Note that since the client no longer requests a specific SPN, it can no longer detect if is connected to a hijacked impersonator of the service, but this is usually a minor concern unless you are really paranoid about security.
Also, as a side rant: the fact that WCF requests as SPN the account name is basically a brain fart. It client should use the DsMakeSpn API to compose the SPN from the service name, host and port. The server should register that SPN for itslef at start up or let an administrator do it using setspn.exe. This is the way they do it by all traditional (well behaved) services in the Kerberos/ActiveDirecotry/Windows environment.
Update
On second though I don't see anything specifying that the client must use the account name as SPN. Looks more like a documentation oversight, instead of documenting the proper way they just recommended what is basically a bad practice. Or maybe just the forum advice is bad, since I did not dig to see what does the MSDN binding spec actually says about the SPN to use...
I don't have a WCF environment handy to test with, but perhaps you can configure the clients to requests a proper SPN like YourService/server:port and you also register the same SPN on the server side. Either manually as an exercise left to the admins, or automatically from your service when it starts up, and unregister it at shut down. The proper way to do it is to let the admins do it, but in reality that is such a pain that most services register the SPN themselves and you can probably follow this practice too. To register an SPN, your service calls DsWriteAccountSpn. The write has to propagate to the AD and be replicated between AD servers, and this at least one reason why having the service auto-register/auto-unregister the SPN is a questionable practice.
If you want to learn more about the wonderfool world of SPNs and how they can wreck your day, you can read up on How Service Publication and Service Principal Names Work.
Update
I'm pretty sure you can use any SPN you like. Most exmaples out there use the account name as 'UPN' (User Principal Name) instead of SPN, but that is just for the convenience of samples as using a true SPN would run into administrative issues setting up the SPN under an user account (again, why admins should do it...). From Overriding the Identity of a Service for Authentication, relevant emphasized:
By default, when a service is
configured to use a Windows
credential, an element that
contains a <userPrincipalName> or
<servicePrincipalName> element is
generated in the WSDL. If the service
is running under the LocalSystem,
LocalService, or NetworkService
account, a service principal name
(SPN) is generated by default in the
form of host/<hostname> because those
accounts have access to the computer's
SPN data. If the service is running
under a different account, Windows
Communication Foundation (WCF)
generates a UPN in the form of
<username>#<domainName>. This occurs
because Kerberos authentication
requires that a UPN or SPN be supplied
to the client to authenticate the
service.
You can also use the Setspn.exe tool
to register an additional SPN with a
service's account in a domain. You can
then use the SPN as the identity of
the service. To download the tool, see
Windows 2000 Resource Kit Tool :
Setspn.exe. For more information about
the tool, see Setspn Overview.
Set NegotiateServiceCredential and EstablishSecurityContext properties to False.

Tomcat authentication using SPNEGO/Kerberos and delegation

Is there an apache module that implements Kerberos authentication for use by Tomcat and also supports Kerberos delegation?
I've already looked at mod_spnego and it throws away the SSPI context it creates only keeping the principal name. Instead, I'm looking for a module that would allow for the delegation of the ticket sent to Tomcat - that is, taking the service ticket sent for authentication and using it server side to access another service on behalf of the user.
EDIT: To clarify, I need to impersonate under Win32 using the GSS/SSPI context so when legacy code connects to another server, the delegated credentials are used.
WAFFLE (Windows Authentication Functional Framework) now provides that feature starting from v1.4beta.
It provides a ServletFilter that uses native Windows APIs to authenticate the user, either using Basic or Negotiate authentication. The user then can be impersonated, and native APIs calls will be performed with the access token of the impersonated user.
How about using the JAAS realm and using the kerberos 5 JAAS module?
http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#JAASRealm
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html
Looks like it might require a little coding, but the pieces should be there.
Here's a http://spnego.sourceforge.net/credential_delegation.html tutorial. It implements Kerberos/SPNEGO as an HTTP Servlet Filter and supports credential delegation.