Initial check-in of the service side components of Casa Auth Token

Authentication.
This commit is contained in:
Juan Carlos Luciani
2006-04-06 16:07:28 +00:00
parent 1387827d5f
commit 7382c46b60
34 changed files with 4951 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry combineaccessrules="false" kind="src" path="/CasaAuthServer"/>
<classpathentry kind="output" path="build/classes"/>
</classpath>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CasaJaasSupport</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,256 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.jaas;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import com.novell.casa.authserver.AuthToken;
import com.novell.casa.authserver.CasaIdentityToken;
/*
* CasaLoginModule Class.
*
* This class implements a LoginModule which performs
* authentication via the Casa Authentication Token
* infrastructure.
*
*/
public class CasaLoginModule implements LoginModule
{
private final static String casaUsername = "CasaIdentityUser";
private Subject m_subject = null;
private CasaPrincipal m_principal = null;
private CallbackHandler m_callbackHandler = null;
private Map m_sharedState = null;
private Map m_options = null;
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#abort()
*/
public boolean abort() throws LoginException
{
// Clear out all of our state
m_subject = null;
m_principal = null;
m_callbackHandler = null;
m_sharedState = null;
m_options = null;
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#commit()
*/
public boolean commit() throws LoginException
{
// Check if we instantiated a principal to associate
// with the subject.
if (m_principal != null)
{
try
{
// Add our principal to the set associated with
// the subject.
m_subject.getPrincipals().add(m_principal);
return true;
}
catch (Exception e)
{
System.err.println("CasaLoginModule.commit()- Exception caught associating principal, msg: " + e.getMessage());
throw new LoginException("Error encountered");
}
}
else
{
// Allways return since authentication failed or was not
// performed by us.
return false;
}
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#login()
*/
public boolean login() throws LoginException
{
// Verify that a CallbackHandler was specified
if (m_callbackHandler == null)
{
System.err.println("CasaLoginModule.login()- Null CallbackHandler");
throw new LoginException("Null CallbackHandler");
}
// Perform the username check unless configured to skip it.
boolean skipUsernameCheck = false;
if (m_options != null
&& m_options.containsKey((String) "skipUsernameCheck") == true)
{
String keyVal = (String) m_options.get("skipUsernameCheck");
if (keyVal == null || keyVal.equals("true"))
skipUsernameCheck = true;
}
if (!skipUsernameCheck)
{
// Verify that the username is CasaIdentityUser, for this
// we first need to obtain it.
//
// Try to obtain the user name from the shared state
String username = (String) m_sharedState.get("javax.security.auth.login.name");
if (username == null)
{
// The usename was not stored in the shared state, request it.
try
{
NameCallback nameCallback = new NameCallback("Enter username:");
Callback[] callbacks = new Callback[1];
callbacks[0] = nameCallback;
m_callbackHandler.handle(callbacks);
username = nameCallback.getName();
}
catch (Exception e)
{
System.err.println("CasaLoginModule.login()- Exception caught during nameCallback, msg: " + e.getMessage());
}
// Check the username
if (username == null)
return false;
else
{
// Save the retrieved username in the shared state and then check it.
m_sharedState.put("javax.security.auth.login.name" , username);
if (username.equals(casaUsername) == false)
return false;
}
}
else
{
// Check the username
if (username.equals(casaUsername) == false)
return false;
}
}
// Obtain the CasaAuthenticationToken
char[] authTokenChars = null;
try
{
PasswordCallback passwordCallback = new PasswordCallback("Enter CasaAuthenticationToken:", false);
Callback[] callbacks = new Callback[1];
callbacks[0] = passwordCallback;
m_callbackHandler.handle(callbacks);
authTokenChars = passwordCallback.getPassword();
}
catch (Exception e)
{
System.err.println("CasaLoginModule.login()- Exception caught during passwordCallback, msg: " + e.getMessage());
}
// Check the CasaAuthenticationToken
if (authTokenChars != null)
{
// Instantiate the AuthToken, this validates the token itself.
try
{
AuthToken authToken = new AuthToken(new String(authTokenChars));
// Instantiate the appropriate IdentityToken based on the IdentityTokenProvider type
// tbd - For now use the CasaIdentityToken
CasaIdentityToken identityToken = new CasaIdentityToken();
identityToken.initialize(authToken.getIdentityToken());
// Now instantiate the CasaPrincipal
m_principal = new CasaPrincipal(identityToken);
}
catch (Exception e)
{
// The validation of one of the tokens failed
// tbd - Log
System.err.println("CasaLoginModule.login()- Exception caught during token processing, msg: " + e.getMessage());
throw new FailedLoginException("Token validation failed");
}
}
else
{
// Token not provided
// tbd - Log
System.err.println("CasaLoginModule.login()- Token not provided");
throw new FailedLoginException("CasaAuthenticationToken not obtained");
}
// User validated
// tbd - Log
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#logout()
*/
public boolean logout() throws LoginException
{
// Check if we must try to remove our principal
// from the associated subject.
if (m_principal != null
&& m_subject.isReadOnly() == false)
{
Set principalSet = m_subject.getPrincipals();
principalSet.remove(m_principal);
}
return true;
}
/*
* (non-Javadoc)
* @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
*/
public void initialize(
Subject subject,
CallbackHandler callbackHandler,
Map sharedState,
Map options)
{
// Save the input parameters for later use
m_subject = subject;
m_callbackHandler = callbackHandler;
m_sharedState = sharedState;
m_options = options;
}
}

View File

@@ -0,0 +1,86 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
***********************************************************************/
package com.novell.casa.jaas;
import java.security.Principal;
import com.novell.casa.authserver.IdentityToken;
/*
* CasaPrincipal class.
*
* This class implements the principal class for
* identities authenticated by Casa.
*
*/
public class CasaPrincipal implements Principal
{
private String m_name;
private String m_realm;
private String m_identStoreUrl;
private javax.naming.directory.Attributes m_attributes;
/*
* Constructor
*/
public CasaPrincipal(IdentityToken identityToken) throws Exception
{
// Get the necessary information from the identity token
m_name = identityToken.getIdentityId();
m_realm = identityToken.getSourceName();
m_identStoreUrl = identityToken.getSourceUrl();
m_attributes = identityToken.getAttributes();
}
/*
* (non-Javadoc)
* @see java.security.Principal#getName()
*/
public String getName()
{
return m_name;
}
/*
* Returns the name associated with the source of the identity data.
*/
public String getRealm()
{
return m_realm;
}
/*
* Returns the url associated with the source of the identity data.
*/
public String getIdentStoreUrl()
{
return m_identStoreUrl;
}
/*
* Returns the identity attributes.
*/
public javax.naming.directory.Attributes getAttributes()
{
return m_attributes;
}
}

View File

@@ -0,0 +1,3 @@
SampleApp {
com.novell.casa.jaas.CasaLoginModule Required debug=true;
};

View File

@@ -0,0 +1,174 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.jaas;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Set;
import javax.naming.NamingEnumeration;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
/*
* This is a sample application which demonstrates the use of
* JAAS and Casa to authenticate a connection.
*/
public class SampleApp
{
/**
* @param args
*/
public static void main(String[] args)
{
Socket sock = null;
ServerSocket listenSock = null;
try
{
// Create a socket to listen for connections
int port = 4444;
int queueLen = 6;
listenSock = new ServerSocket(port, queueLen);
// Service connections
while (true)
{
BufferedReader in = null;
try
{
// Wait for the next connection
System.out.println("Waiting for connection");
sock = listenSock.accept();
System.out.println();
System.out.println("********Connection received*********");
// Get socket I/O streams
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
//PrintStream out = new PrintStream(sock.getOutputStream());
// Get the authentication token from the client
String authToken = in.readLine();
//System.out.println("Token received from client, length = " + authToken.length());
// Authenticate the token and print out the information available to our service
// about the authenticated identity.
try
{
LoginContext lc = new LoginContext("SampleApp", new SampleAppCallbackHandler(authToken));
System.out.println("Authenticating the user");
lc.login();
System.out.println(" Authentication succeeded");
// Now get the subject associated with the context
Subject subject = lc.getSubject();
// Now get the CasaPrincipals that represent the authenticated
// identity or identities.
Set principalSet = subject.getPrincipals(CasaPrincipal.class);
//System.out.println("The number of CasaPrincipals is: " + principalSet.size());
Iterator principalIter = principalSet.iterator();
System.out.println();
System.out.println("Authenticated Identity Information");
System.out.println();
while (principalIter.hasNext() == true)
{
CasaPrincipal principal = (CasaPrincipal) principalIter.next();
// Print out information about the principal
System.out.println(" Source of the identity information: " + principal.getIdentStoreUrl());
System.out.println(" Realm name associated with identity source: " + principal.getRealm());
System.out.println(" Principal name (unique within identity source realm): " + principal.getName());
System.out.println();
System.out.println("Authenticated Identity Attributes");
System.out.println();
javax.naming.directory.Attributes attrs = principal.getAttributes();
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();)
{
javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) ae.next();
NamingEnumeration enumeration = attr.getAll();
while (enumeration.hasMore())
{
System.out.print(" Attribute Name: " + attr.getID());
System.out.println(" :: Attribute Value: " + (String) enumeration.next());
}
}
}
System.out.println();
}
catch (LoginException e)
{
System.out.println(" Authentication failed");
}
}
finally
{
if (sock != null)
{
sock.close();
sock = null;
}
if (in != null)
in.close();
}
}
}
catch (IOException e)
{
System.out.println("IOException: " + e.getMessage());
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage());
}
finally
{
try
{
if (sock != null)
{
sock.close();
}
if (listenSock != null)
{
listenSock.close();
}
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage());
}
}
}
}

View File

@@ -0,0 +1,71 @@
/***********************************************************************
*
* Copyright (C) 2006 Novell, Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, Novell, Inc.
*
* To contact Novell about this file by physical or electronic mail,
* you may find current contact information at www.novell.com.
*
* Author: Juan Carlos Luciani <jluciani@novell.com>
*
***********************************************************************/
package com.novell.casa.jaas;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
public class SampleAppCallbackHandler implements CallbackHandler
{
private String m_authToken;
/*
* Constructor
*
*/
public SampleAppCallbackHandler(String authToken)
{
m_authToken = authToken;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
{
for (int i = 0; i < callbacks.length; i++)
{
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
nc.setName("CasaIdentityUser");
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
//System.out.println("SampleAppCallbackHandler.handle()- Token length = " + m_authToken.length());
char[] allChars = m_authToken.toCharArray();
// Remove the null terminator
char[] tokenChars = new char[allChars.length - 1];
for (int ii = 0; ii < tokenChars.length; ii++)
tokenChars[ii] = allChars[ii];
pc.setPassword(tokenChars);
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}