mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
Updates to Kerberos logon code to add options that are available in 2.x. (<kerbersoDebug/> and <disableNTLM/>).
Removed need for <Principal> config if domain was used, now gets the principal automatically after the service logon. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10465 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
99bc588c38
commit
25dcd6bccf
@ -228,6 +228,19 @@ public abstract class CifsAuthenticatorBase extends CifsAuthenticator
|
|||||||
tx.begin();
|
tx.begin();
|
||||||
personName = m_alfrescoConfig.getPersonService().getUserIdentifier( userName);
|
personName = m_alfrescoConfig.getPersonService().getUserIdentifier( userName);
|
||||||
tx.commit();
|
tx.commit();
|
||||||
|
|
||||||
|
// Check if the person exists
|
||||||
|
|
||||||
|
if (personName == null) {
|
||||||
|
|
||||||
|
tx = m_alfrescoConfig.getTransactionService().getNonPropagatingUserTransaction( false);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
|
m_alfrescoConfig.getPersonService().getPerson( userName);
|
||||||
|
personName = m_alfrescoConfig.getPersonService().getUserIdentifier( userName);
|
||||||
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable ex)
|
catch (Throwable ex)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ package org.alfresco.filesys.auth.cifs;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.Principal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
@ -50,7 +51,9 @@ import org.alfresco.jlan.debug.Debug;
|
|||||||
import org.alfresco.jlan.server.auth.AuthenticatorException;
|
import org.alfresco.jlan.server.auth.AuthenticatorException;
|
||||||
import org.alfresco.jlan.server.auth.ClientInfo;
|
import org.alfresco.jlan.server.auth.ClientInfo;
|
||||||
import org.alfresco.jlan.server.auth.NTLanManAuthContext;
|
import org.alfresco.jlan.server.auth.NTLanManAuthContext;
|
||||||
|
import org.alfresco.jlan.server.auth.kerberos.KerberosApReq;
|
||||||
import org.alfresco.jlan.server.auth.kerberos.KerberosDetails;
|
import org.alfresco.jlan.server.auth.kerberos.KerberosDetails;
|
||||||
|
import org.alfresco.jlan.server.auth.kerberos.KrbAuthContext;
|
||||||
import org.alfresco.jlan.server.auth.kerberos.SessionSetupPrivilegedAction;
|
import org.alfresco.jlan.server.auth.kerberos.SessionSetupPrivilegedAction;
|
||||||
import org.alfresco.jlan.server.auth.ntlm.NTLM;
|
import org.alfresco.jlan.server.auth.ntlm.NTLM;
|
||||||
import org.alfresco.jlan.server.auth.ntlm.NTLMMessage;
|
import org.alfresco.jlan.server.auth.ntlm.NTLMMessage;
|
||||||
@ -157,6 +160,16 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
{
|
{
|
||||||
super.initialize(config, params);
|
super.initialize(config, params);
|
||||||
|
|
||||||
|
// Check if Java API Kerberos debug output should be enabled
|
||||||
|
|
||||||
|
if ( params.getChild("kerberosDebug") != null)
|
||||||
|
{
|
||||||
|
// Enable Kerberos API debug output
|
||||||
|
|
||||||
|
System.setProperty( "sun.security.jgss.debug", "true");
|
||||||
|
System.setProperty( "sun.security.krb5.debug", "true");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if Kerberos is enabled, get the Kerberos KDC address
|
// Check if Kerberos is enabled, get the Kerberos KDC address
|
||||||
|
|
||||||
ConfigElement kdcAddress = params.getChild("KDC");
|
ConfigElement kdcAddress = params.getChild("KDC");
|
||||||
@ -207,17 +220,6 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
throw new InvalidConfigurationException("Invalid login entry specified");
|
throw new InvalidConfigurationException("Invalid login entry specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the CIFS service account name
|
|
||||||
|
|
||||||
StringBuilder cifsAccount = new StringBuilder();
|
|
||||||
|
|
||||||
cifsAccount.append("cifs/");
|
|
||||||
cifsAccount.append( config.getServerName().toLowerCase());
|
|
||||||
cifsAccount.append("@");
|
|
||||||
cifsAccount.append(m_krbRealm);
|
|
||||||
|
|
||||||
m_accountName = cifsAccount.toString();
|
|
||||||
|
|
||||||
// Create a login context for the CIFS server service
|
// Create a login context for the CIFS server service
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -237,14 +239,46 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
throw new InvalidConfigurationException("Failed to login CIFS server service");
|
throw new InvalidConfigurationException("Failed to login CIFS server service");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the CIFS service account name from the subject
|
||||||
|
|
||||||
|
Subject subj = m_loginContext.getSubject();
|
||||||
|
Principal princ = subj.getPrincipals().iterator().next();
|
||||||
|
|
||||||
|
m_accountName = princ.getName();
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Logged on using principal " + m_accountName);
|
||||||
|
|
||||||
// Create the Oid list for the SPNEGO NegTokenInit, include NTLMSSP for fallback
|
// Create the Oid list for the SPNEGO NegTokenInit, include NTLMSSP for fallback
|
||||||
|
|
||||||
Vector<Oid> mechTypes = new Vector<Oid>();
|
Vector<Oid> mechTypes = new Vector<Oid>();
|
||||||
|
|
||||||
mechTypes.add(OID.NTLMSSP);
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Enabling mechTypes :-");
|
||||||
|
logger.debug(" Kerberos5");
|
||||||
|
logger.debug(" MS-Kerberos5");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always enable Kerberos
|
||||||
|
|
||||||
mechTypes.add(OID.KERBEROS5);
|
mechTypes.add(OID.KERBEROS5);
|
||||||
mechTypes.add(OID.MSKERBEROS5);
|
mechTypes.add(OID.MSKERBEROS5);
|
||||||
|
|
||||||
|
if ( params.getChild("disableNTLM") == null)
|
||||||
|
{
|
||||||
|
mechTypes.add(OID.NTLMSSP);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug(" NTLMSSP");
|
||||||
|
}
|
||||||
|
|
||||||
// Build the SPNEGO NegTokenInit blob
|
// Build the SPNEGO NegTokenInit blob
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -402,7 +436,8 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
if (callbacks[i] instanceof NameCallback)
|
if (callbacks[i] instanceof NameCallback)
|
||||||
{
|
{
|
||||||
NameCallback cb = (NameCallback) callbacks[i];
|
NameCallback cb = (NameCallback) callbacks[i];
|
||||||
cb.setName(m_accountName);
|
// cb.setName(m_accountName);
|
||||||
|
cb.setName("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request for password
|
// Request for password
|
||||||
@ -1281,6 +1316,49 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Parse the mechToken to get the AP-REQ details
|
||||||
|
|
||||||
|
KerberosApReq krbApReq = new KerberosApReq();
|
||||||
|
krbApReq.parseMechToken( negToken.getMechtoken());
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug( "Kerberos AP-REQ - " + krbApReq);
|
||||||
|
|
||||||
|
// Check if mutual authentication is required
|
||||||
|
|
||||||
|
KrbAuthContext krbAuthCtx = null;
|
||||||
|
|
||||||
|
if ( krbApReq.hasMutualAuthentication())
|
||||||
|
{
|
||||||
|
// Allocate the Kerberos authentication and parse the AP-REQ
|
||||||
|
|
||||||
|
krbAuthCtx = new KrbAuthContext();
|
||||||
|
krbAuthCtx.setDebug(hasDebug());
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Kerberos mutual auth required, parsing AP-REQ");
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Parse the AP-REQ
|
||||||
|
|
||||||
|
krbAuthCtx.parseKerberosApReq( m_loginContext.getSubject(), krbApReq);
|
||||||
|
}
|
||||||
|
catch ( IOException ex)
|
||||||
|
{
|
||||||
|
// Failed to parse AP-REQ
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Failed to parse AP-REQ, " + ex.toString());
|
||||||
|
|
||||||
|
// Return a logon failure status
|
||||||
|
|
||||||
|
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run the session setup as a privileged action
|
// Run the session setup as a privileged action
|
||||||
|
|
||||||
SessionSetupPrivilegedAction sessSetupAction = new SessionSetupPrivilegedAction( m_accountName, negToken.getMechtoken());
|
SessionSetupPrivilegedAction sessSetupAction = new SessionSetupPrivilegedAction( m_accountName, negToken.getMechtoken());
|
||||||
@ -1292,11 +1370,94 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
|
|
||||||
krbDetails = (KerberosDetails) result;
|
krbDetails = (KerberosDetails) result;
|
||||||
|
|
||||||
|
// Determine the response OID
|
||||||
|
|
||||||
|
Oid respOid = null;
|
||||||
|
|
||||||
|
if ( negToken.hasOid( OID.MSKERBEROS5))
|
||||||
|
{
|
||||||
|
respOid = OID.MSKERBEROS5;
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Using OID MS Kerberos5 for NegTokenTarg");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
respOid = OID.KERBEROS5;
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Using OID Kerberos5 for NegTokenTarg");
|
||||||
|
}
|
||||||
|
|
||||||
|
// If mutual authentication is required then we unpack the AP-REP and add in the missing
|
||||||
|
// subkey that the AD client requires
|
||||||
|
|
||||||
|
if ( krbAuthCtx != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse the AP-REP and add the missing subkey, return the updated response blob
|
||||||
|
|
||||||
|
byte[] respToken = krbAuthCtx.parseKerberosApRep( krbDetails.getResponseToken());
|
||||||
|
krbDetails.setResponseToken(respToken);
|
||||||
|
|
||||||
|
// Create the NegtokenTarg
|
||||||
|
|
||||||
|
negTokenTarg = new NegTokenTarg( SPNEGO.AcceptCompleted, respOid, krbDetails.getResponseToken());
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Created NegTokenTarg using updated AP-REP, added subkey");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if ( logger.isDebugEnabled()) {
|
||||||
|
logger.debug("AP-REP Error:");
|
||||||
|
logger.debug( ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Create the NegTokenTarg response blob
|
// Create the NegTokenTarg response blob
|
||||||
|
|
||||||
negTokenTarg = new NegTokenTarg( SPNEGO.AcceptCompleted, OID.KERBEROS5, krbDetails.getResponseToken());
|
negTokenTarg = new NegTokenTarg( SPNEGO.AcceptCompleted, respOid, krbDetails.getResponseToken());
|
||||||
|
|
||||||
// Setup the Acegi authenticated user
|
// DEBUG
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Created NegTokenTarg using standard Krb5 API response");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is a null logon
|
||||||
|
|
||||||
|
String userName = krbDetails.getUserName();
|
||||||
|
|
||||||
|
if ( userName != null)
|
||||||
|
{
|
||||||
|
// Check for the machine account name
|
||||||
|
|
||||||
|
if ( userName.endsWith( "$") && userName.equals( userName.toUpperCase()))
|
||||||
|
{
|
||||||
|
// Null logon
|
||||||
|
|
||||||
|
client.setLogonType( ClientInfo.LogonNull);
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug("Machine account logon, " + userName + ", as null logon");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the system user to do the user name lookup
|
||||||
|
|
||||||
|
getAuthenticationComponent().setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
// Set the current user to be authenticated, save the authentication token
|
// Set the current user to be authenticated, save the authentication token
|
||||||
|
|
||||||
@ -1310,23 +1471,49 @@ public class EnterpriseCifsAuthenticator extends CifsAuthenticatorBase implement
|
|||||||
|
|
||||||
// Indicate that the session is logged on
|
// Indicate that the session is logged on
|
||||||
|
|
||||||
|
sess.setLoggedOn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Null logon
|
||||||
|
|
||||||
|
client.setLogonType( ClientInfo.LogonNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicate that the session is logged on
|
||||||
|
|
||||||
sess.setLoggedOn(true);
|
sess.setLoggedOn(true);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
|
||||||
if ( logger.isDebugEnabled())
|
if ( logger.isDebugEnabled())
|
||||||
logger.debug("Logged on using Kerberos");
|
logger.debug("Logged on using Kerberos, user " + userName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Debug
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled())
|
||||||
|
logger.debug( "No SPNEGO response, Kerberos logon failed");
|
||||||
|
|
||||||
|
// Return a logon failure status
|
||||||
|
|
||||||
|
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Log the error
|
// Log the error
|
||||||
|
|
||||||
|
if ( logger.isErrorEnabled()) {
|
||||||
|
logger.error("Kerberos logon error");
|
||||||
logger.error(ex);
|
logger.error(ex);
|
||||||
|
}
|
||||||
|
|
||||||
// Return a logon failure status
|
// Return a logon failure status
|
||||||
|
|
||||||
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
|
throw new SMBSrvException( SMBStatus.NTLogonFailure, SMBStatus.ErrDos, SMBStatus.DOSAccessDenied);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the response SPNEGO blob
|
// Return the response SPNEGO blob
|
||||||
|
Loading…
x
Reference in New Issue
Block a user