mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merge of BRANCHES/DEV/4.2_ENT_DEV/ADMIN_CONSOLE - Admin Console 46247-46672
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@46677 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
@@ -160,9 +161,11 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
try
|
||||
{
|
||||
authenticateImpl(userName, password);
|
||||
onAuthenticate();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
onFail();
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Failed to authenticate user \"" + userName + '"', e);
|
||||
@@ -661,4 +664,26 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
{
|
||||
return authenticationContext.setUserDetails(ud);
|
||||
}
|
||||
|
||||
AtomicInteger numberSuccessfulAuthentications = new AtomicInteger(0);
|
||||
AtomicInteger numberFailedAuthentications = new AtomicInteger(0);
|
||||
protected void onAuthenticate()
|
||||
{
|
||||
numberSuccessfulAuthentications.getAndIncrement();
|
||||
}
|
||||
|
||||
protected void onFail()
|
||||
{
|
||||
numberFailedAuthentications.getAndIncrement();
|
||||
}
|
||||
|
||||
public int getNumberSuccessfulAuthentications()
|
||||
{
|
||||
return numberSuccessfulAuthentications.get();
|
||||
}
|
||||
|
||||
public int getNumberFailedAuthentications()
|
||||
{
|
||||
return numberFailedAuthentications.get();
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,8 @@ import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
/**
|
||||
@@ -40,6 +42,13 @@ public abstract class AbstractChainingAuthenticationComponent extends AbstractAu
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication component with the specified name
|
||||
* @param name
|
||||
* @return the authentication component or null if it does not exist
|
||||
*/
|
||||
protected abstract AuthenticationComponent getAuthenticationComponent(String name);
|
||||
|
||||
/**
|
||||
* Gets the authentication components across which methods will chain.
|
||||
@@ -55,6 +64,8 @@ public abstract class AbstractChainingAuthenticationComponent extends AbstractAu
|
||||
* the user name
|
||||
* @param password
|
||||
* the password
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
@Override
|
||||
protected void authenticateImpl(String userName, char[] password)
|
||||
@@ -73,6 +84,44 @@ public abstract class AbstractChainingAuthenticationComponent extends AbstractAu
|
||||
}
|
||||
throw new AuthenticationException("Failed to authenticate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test authenticate with a specific authenticator and user name and password.
|
||||
*
|
||||
* @param authenticatorName
|
||||
* the name of the authenticator to use
|
||||
* @param userName
|
||||
* the user name
|
||||
* @param password
|
||||
* the password
|
||||
* @throws AuthenticationException including diagnostic information about the failure
|
||||
*/
|
||||
public void testAuthenticate(String authenticatorName, String userName, char[] password)
|
||||
{
|
||||
|
||||
AuthenticationComponent authenticationComponent = getAuthenticationComponent(authenticatorName);
|
||||
if(authenticationComponent != null)
|
||||
{
|
||||
if (authenticationComponent instanceof ActivateableBean)
|
||||
{
|
||||
if(!((ActivateableBean) authenticationComponent).isActive())
|
||||
{
|
||||
AuthenticationDiagnostic diagnostic = new AuthenticationDiagnostic();
|
||||
Object[] args = {authenticatorName};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION_AUTHENTICATOR_NOT_ACTIVE, false, args);
|
||||
throw new AuthenticationException("authentication.err.validation.authenticator.notactive", args , diagnostic);
|
||||
}
|
||||
}
|
||||
|
||||
authenticationComponent.authenticate(userName, password);
|
||||
return;
|
||||
}
|
||||
|
||||
AuthenticationDiagnostic diagnostic = new AuthenticationDiagnostic();
|
||||
Object[] args = {authenticatorName};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION_AUTHENTICATOR_NOT_FOUND, false, args);
|
||||
throw new AuthenticationException("authentication.err.validation.authenticator.notfound", args , diagnostic);
|
||||
}
|
||||
|
||||
/**
|
||||
* If any implementation supports guest then guest is allowed.
|
||||
|
@@ -27,8 +27,8 @@ import net.sf.acegisecurity.Authentication;
|
||||
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
|
||||
|
||||
/**
|
||||
* A chaining authentication component is required for all the beans that qire up an authentication component and not an
|
||||
* authentication service. It supports chaining in much the same way and wires up components in the same way asthe
|
||||
* A chaining authentication component is required for all the beans that wire up an authentication component and not an
|
||||
* authentication service. It supports chaining in much the same way and wires up components in the same way as the
|
||||
* chaining authentication service wires up services.
|
||||
*
|
||||
* @author andyh
|
||||
@@ -306,4 +306,11 @@ public class ChainingAuthenticationComponentImpl extends AbstractChainingAuthent
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthenticationComponent getAuthenticationComponent(String name)
|
||||
{
|
||||
// not implemented
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||
import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationDiagnostic;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.sync.ldap.LDAPNameResolver;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -109,17 +110,35 @@ public class LDAPAuthenticationComponentImpl extends AbstractAuthenticationCompo
|
||||
*/
|
||||
protected void authenticateImpl(String userName, char[] password) throws AuthenticationException
|
||||
{
|
||||
// If we aren't using a fixed name format, do a search to resolve the user DN
|
||||
String userDN = userNameFormat == null ? ldapNameResolver.resolveDistinguishedName(userName) : String.format(
|
||||
userNameFormat, new Object[]
|
||||
{
|
||||
escapeUserName(userName, escapeCommasInBind)
|
||||
});
|
||||
// Distinguished name of user.
|
||||
String userDN;
|
||||
|
||||
AuthenticationDiagnostic diagnostic = new AuthenticationDiagnostic();
|
||||
|
||||
if(userNameFormat == null)
|
||||
{
|
||||
// If we aren't using a fixed name format, do a search to resolve the user DN
|
||||
userDN = ldapNameResolver.resolveDistinguishedName(userName, diagnostic);
|
||||
|
||||
Object[] params = {userName, userDN};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_LOOKEDUP_USER, true, params);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are using a fixed name format,
|
||||
userDN = String.format(
|
||||
userNameFormat, new Object[]
|
||||
{
|
||||
escapeUserName(userName, escapeCommasInBind)
|
||||
});
|
||||
Object[] params = {userName, userDN, userNameFormat};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_FORMAT_USER, true, params);
|
||||
}
|
||||
|
||||
InitialDirContext ctx = null;
|
||||
try
|
||||
{
|
||||
ctx = ldapInitialContextFactory.getInitialDirContext(userDN, new String(password));
|
||||
ctx = ldapInitialContextFactory.getInitialDirContext(userDN, new String(password), diagnostic);
|
||||
|
||||
// Authentication has been successful.
|
||||
// Set the current user, they are now authenticated.
|
||||
|
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationDiagnostic;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
|
||||
/**
|
||||
@@ -39,6 +40,20 @@ public interface LDAPInitialDirContextFactory
|
||||
*/
|
||||
public void setInitialDirContextEnvironment(Map<String, String> environment);
|
||||
|
||||
/**
|
||||
* Use the environment properties and connect to the LDAP server, optionally configuring RFC 2696 paged results.
|
||||
* Used to obtain read only access to the LDAP server.
|
||||
*
|
||||
* @param pageSize
|
||||
* if a positive value, indicates that a LDAP v3 RFC 2696 paged results control should be used. The
|
||||
* results of a search operation should be returned by the LDAP server in batches of the specified size.
|
||||
* @param diagnostic
|
||||
* @return the default intial dir context
|
||||
* @throws AuthenticationException
|
||||
* the authentication exception
|
||||
*/
|
||||
public InitialDirContext getDefaultIntialDirContext(int pageSize, AuthenticationDiagnostic diagnostic) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Use the environment properties and connect to the LDAP server, optionally configuring RFC 2696 paged results.
|
||||
* Used to obtain read only access to the LDAP server.
|
||||
@@ -61,6 +76,15 @@ public interface LDAPInitialDirContextFactory
|
||||
*/
|
||||
public InitialDirContext getDefaultIntialDirContext() throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Use the environment properties and connect to the LDAP server.
|
||||
* Used to obtain read only access to the LDAP server.
|
||||
*
|
||||
* @return
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public InitialDirContext getDefaultIntialDirContext(AuthenticationDiagnostic diagnostic) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Determines whether there is another page to fetch from the last search to be run in this context. Also prepares
|
||||
* the request controls so that the appropriate cookie will be passed in the next search.
|
||||
@@ -72,8 +96,8 @@ public interface LDAPInitialDirContextFactory
|
||||
* results of a search operation should be returned by the LDAP server in batches of the specified size.
|
||||
* @return true, if is ready for next page
|
||||
*/
|
||||
public boolean hasNextPage(DirContext ctx, int pageSize);
|
||||
|
||||
public boolean hasNextPage(DirContext ctx, int pageSize);
|
||||
|
||||
/**
|
||||
* Augment the connection environment with the identity and credentials and bind to the ldap server.
|
||||
* Mainly used to validate a user's credentials during authentication.
|
||||
@@ -84,4 +108,16 @@ public interface LDAPInitialDirContextFactory
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public InitialDirContext getInitialDirContext(String principal, String credentials) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Augment the connection environment with the identity and credentials and bind to the ldap server.
|
||||
* Mainly used to validate a user's credentials during authentication.
|
||||
*
|
||||
* @param principal
|
||||
* @param credentials
|
||||
* @param diagnostic
|
||||
* @return
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public InitialDirContext getInitialDirContext(String principal, String credentials, AuthenticationDiagnostic diagnostic) throws AuthenticationException;
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.naming.AuthenticationNotSupportedException;
|
||||
import javax.naming.CommunicationException;
|
||||
import javax.naming.Context;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
@@ -40,6 +41,7 @@ import javax.naming.ldap.LdapContext;
|
||||
import javax.naming.ldap.PagedResultsControl;
|
||||
import javax.naming.ldap.PagedResultsResponseControl;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationDiagnostic;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -84,19 +86,38 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
|
||||
public InitialDirContext getDefaultIntialDirContext() throws AuthenticationException
|
||||
{
|
||||
return getDefaultIntialDirContext(0);
|
||||
return getDefaultIntialDirContext(0, new AuthenticationDiagnostic());
|
||||
}
|
||||
|
||||
public InitialDirContext getDefaultIntialDirContext(int pageSize) throws AuthenticationException
|
||||
{
|
||||
return getDefaultIntialDirContext(pageSize, new AuthenticationDiagnostic());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InitialDirContext getDefaultIntialDirContext(
|
||||
AuthenticationDiagnostic diagnostic) throws AuthenticationException
|
||||
{
|
||||
return getDefaultIntialDirContext(0, diagnostic);
|
||||
}
|
||||
|
||||
public InitialDirContext getDefaultIntialDirContext(int pageSize) throws AuthenticationException
|
||||
public InitialDirContext getDefaultIntialDirContext(int pageSize, AuthenticationDiagnostic diagnostic) throws AuthenticationException
|
||||
{
|
||||
Hashtable<String, String> env = new Hashtable<String, String>(defaultEnvironment.size());
|
||||
env.putAll(defaultEnvironment);
|
||||
return buildInitialDirContext(env, pageSize);
|
||||
return buildInitialDirContext(env, pageSize, diagnostic);
|
||||
}
|
||||
|
||||
private InitialDirContext buildInitialDirContext(Hashtable<String, String> env, int pageSize)
|
||||
private InitialDirContext buildInitialDirContext(Hashtable<String, String> env, int pageSize, AuthenticationDiagnostic diagnostic)
|
||||
throws AuthenticationException
|
||||
{
|
||||
String securityPrincipal = env.get(Context.SECURITY_PRINCIPAL);
|
||||
String providerURL = env.get(Context.PROVIDER_URL);
|
||||
|
||||
if(diagnostic == null)
|
||||
{
|
||||
diagnostic = new AuthenticationDiagnostic();
|
||||
}
|
||||
try
|
||||
{
|
||||
// If a page size has been requested, use LDAP v3 paging
|
||||
@@ -111,20 +132,71 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
}
|
||||
else
|
||||
{
|
||||
return new InitialDirContext(env);
|
||||
InitialDirContext ret = new InitialDirContext(env);
|
||||
Object[] args = {providerURL, securityPrincipal};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_CONNECTED, true, args);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
catch (javax.naming.AuthenticationException ax)
|
||||
{
|
||||
throw new AuthenticationException("LDAP authentication failed.", ax);
|
||||
Object[] args1 = {securityPrincipal};
|
||||
Object[] args = {providerURL, securityPrincipal};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_CONNECTED, true, args);
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_AUTHENTICATION, false, args1);
|
||||
|
||||
// wrong user/password - if we get this far the connection is O.K
|
||||
Object[] args2 = {securityPrincipal, ax.getLocalizedMessage()};
|
||||
throw new AuthenticationException("authentication.err.authentication", diagnostic, args2, ax);
|
||||
}
|
||||
catch (CommunicationException ce)
|
||||
{
|
||||
Object[] args1 = {providerURL};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_CONNECTING, false, args1);
|
||||
|
||||
StringBuffer message = new StringBuffer();
|
||||
|
||||
message.append(ce.getClass().getName() + ", " + ce.getMessage());
|
||||
|
||||
Throwable cause = ce.getCause();
|
||||
while (cause != null)
|
||||
{
|
||||
message.append(", ");
|
||||
message.append(cause.getClass().getName() + ", " + cause.getMessage());
|
||||
cause = cause.getCause();
|
||||
}
|
||||
|
||||
// failed to connect
|
||||
Object[] args = {providerURL, message.toString()};
|
||||
throw new AuthenticationException("authentication.err.communication", diagnostic, args, cause);
|
||||
}
|
||||
catch (NamingException nx)
|
||||
{
|
||||
throw new AuthenticationException("Unable to connect to LDAP Server; check LDAP configuration", nx);
|
||||
Object[] args = {providerURL};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_CONNECTING, false, args);
|
||||
|
||||
StringBuffer message = new StringBuffer();
|
||||
|
||||
message.append(nx.getClass().getName() + ", " + nx.getMessage());
|
||||
|
||||
Throwable cause = nx.getCause();
|
||||
while (cause != null)
|
||||
{
|
||||
message.append(", ");
|
||||
message.append(cause.getClass().getName() + ", " + cause.getMessage());
|
||||
cause = cause.getCause();
|
||||
}
|
||||
|
||||
// failed to connect
|
||||
Object[] args1 = {providerURL, message.toString()};
|
||||
throw new AuthenticationException("authentication.err.connection", diagnostic, args1, nx);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new AuthenticationException("Unable to encode LDAP v3 request controls; check LDAP configuration", e);
|
||||
Object[] args = {providerURL, securityPrincipal};
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_LDAP_CONNECTED, true, args);
|
||||
|
||||
throw new AuthenticationException("Unable to encode LDAP v3 request controls", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,36 +243,58 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public InitialDirContext getInitialDirContext(String principal, String credentials) throws AuthenticationException
|
||||
|
||||
@Override
|
||||
public InitialDirContext getInitialDirContext(String principal,
|
||||
String credentials)
|
||||
throws AuthenticationException
|
||||
{
|
||||
return getInitialDirContext(principal, credentials, null);
|
||||
}
|
||||
|
||||
public InitialDirContext getInitialDirContext(String principal, String credentials, AuthenticationDiagnostic diagnostic) throws AuthenticationException
|
||||
{
|
||||
if(diagnostic == null)
|
||||
{
|
||||
diagnostic = new AuthenticationDiagnostic();
|
||||
}
|
||||
|
||||
if (principal == null)
|
||||
{
|
||||
throw new AuthenticationException("Null user name provided.");
|
||||
// failed before we tried to do anything
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION, false, null);
|
||||
throw new AuthenticationException("Null user name provided.", diagnostic);
|
||||
}
|
||||
|
||||
if (principal.length() == 0)
|
||||
{
|
||||
throw new AuthenticationException("Empty user name provided.");
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION, false, null);
|
||||
throw new AuthenticationException("Empty user name provided.", diagnostic);
|
||||
}
|
||||
|
||||
if (credentials == null)
|
||||
{
|
||||
throw new AuthenticationException("No credentials provided.");
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION, false, null);
|
||||
throw new AuthenticationException("No credentials provided.", diagnostic);
|
||||
}
|
||||
|
||||
if (credentials.length() == 0)
|
||||
{
|
||||
throw new AuthenticationException("Empty credentials provided.");
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION, false, null);
|
||||
throw new AuthenticationException("Empty credentials provided.", diagnostic);
|
||||
}
|
||||
|
||||
diagnostic.addStep(AuthenticationDiagnostic.STEP_KEY_VALIDATION, true, null);
|
||||
|
||||
Hashtable<String, String> env = new Hashtable<String, String>(authenticatedEnvironment.size());
|
||||
env.putAll(authenticatedEnvironment);
|
||||
env.put(Context.SECURITY_PRINCIPAL, principal);
|
||||
env.put(Context.SECURITY_CREDENTIALS, credentials);
|
||||
|
||||
return buildInitialDirContext(env, 0);
|
||||
return buildInitialDirContext(env, 0, diagnostic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
@@ -291,6 +385,7 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
logger.debug("after Properties Set");
|
||||
// Check Anonymous bind
|
||||
|
||||
Hashtable<String, String> env = new Hashtable<String, String>(authenticatedEnvironment.size());
|
||||
@@ -417,4 +512,8 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.ldap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeDataSupport;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
import javax.management.openmbean.OpenDataException;
|
||||
import javax.management.openmbean.OpenType;
|
||||
import javax.management.openmbean.SimpleType;
|
||||
import javax.management.openmbean.TabularData;
|
||||
import javax.management.openmbean.TabularDataSupport;
|
||||
import javax.management.openmbean.TabularType;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationStep;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Monitoring methods and properties to be exposed via the
|
||||
* JMX admin console.
|
||||
*/
|
||||
|
||||
public class Monitor
|
||||
{
|
||||
LDAPAuthenticationComponentImpl component;
|
||||
|
||||
private static Log logger = LogFactory.getLog(Monitor.class);
|
||||
|
||||
public void setLDAPAuthenticationComponent(LDAPAuthenticationComponentImpl component)
|
||||
{
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public String getAuthenticatorType()
|
||||
{
|
||||
return "ldap";
|
||||
}
|
||||
|
||||
/**
|
||||
* test authenticate
|
||||
*
|
||||
* @param userName
|
||||
* @param credentials
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public CompositeData testAuthenticate(String userName, String credentials)
|
||||
{
|
||||
String stepKeys[] = {"id", "stepMessage", "success"};
|
||||
String stepDescriptions[] = {"id", "stepMessage", "success"};
|
||||
OpenType<?> stepTypes[] = {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN };
|
||||
|
||||
try
|
||||
{
|
||||
String[] key = {"id"};
|
||||
CompositeType sType = new CompositeType("Authentication Step", "Step", stepKeys, stepDescriptions, stepTypes);
|
||||
TabularType tType = new TabularType("Diagnostic", "Authentication Steps", sType, key);
|
||||
TabularData table = new TabularDataSupport(tType);
|
||||
|
||||
String attributeKeys[] = {"authenticationMessage", "success", "diagnostic"};
|
||||
String attributeDescriptions[] = {"authenticationMessage", "success", "diagnostic"};
|
||||
OpenType<?> attributeTypes[] = {SimpleType.STRING, SimpleType.BOOLEAN, tType};
|
||||
try
|
||||
{
|
||||
component.authenticate(userName, credentials.toCharArray());
|
||||
|
||||
CompositeType cType = new CompositeType("Authentication Result", "Result Success", attributeKeys, attributeDescriptions, attributeTypes);
|
||||
Map<String, Object> value = new HashMap<String, Object>();
|
||||
value.put("authenticationMessage", "Test Passed");
|
||||
value.put("success", true);
|
||||
value.put("diagnostic", table);
|
||||
CompositeDataSupport row = new CompositeDataSupport(cType, value);
|
||||
return row;
|
||||
}
|
||||
catch (AuthenticationException ae)
|
||||
{
|
||||
CompositeType cType = new CompositeType("Authentication Result", "Result Failed", attributeKeys, attributeDescriptions, attributeTypes);
|
||||
Map<String, Object> value = new HashMap<String, Object>();
|
||||
value.put("authenticationMessage", ae.getMessage());
|
||||
value.put("success", false);
|
||||
|
||||
if(ae.getDiagnostic() != null)
|
||||
{
|
||||
int i = 0;
|
||||
for(AuthenticationStep step : ae.getDiagnostic().getSteps())
|
||||
{
|
||||
Map<String, Object> x = new HashMap<String, Object>();
|
||||
x.put("id", i++);
|
||||
x.put("stepMessage", step.getMessage());
|
||||
x.put("success", step.isSuccess());
|
||||
CompositeDataSupport row = new CompositeDataSupport(sType, x);
|
||||
table.put(row);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
value.put("diagnostic", table);
|
||||
|
||||
CompositeDataSupport row = new CompositeDataSupport(cType, value);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
}
|
||||
catch (OpenDataException oe)
|
||||
{
|
||||
logger.error("", oe);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberFailedAuthentications()
|
||||
{
|
||||
return component.getNumberFailedAuthentications();
|
||||
}
|
||||
|
||||
public int getNumberSuccessfulAuthentications()
|
||||
{
|
||||
return component.getNumberSuccessfulAuthentications();
|
||||
}
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco 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, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.ldap;
|
||||
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.SimpleBeanInfo;
|
||||
/**
|
||||
* A BeanInfo providing metadata for the Monitor class
|
||||
*
|
||||
* @author mrogers
|
||||
*/
|
||||
public class MonitorBeanInfo extends SimpleBeanInfo
|
||||
{
|
||||
/**
|
||||
* Gets the beans <code>BeanDescriptor</code>.
|
||||
*
|
||||
* @return A BeanDescriptor providing overall information about
|
||||
* the bean, such as its displayName, its customizer, etc. May
|
||||
* return null if the information should be obtained by automatic
|
||||
* analysis.
|
||||
*/
|
||||
// BeanDescriptor getBeanDescriptor();
|
||||
|
||||
/**
|
||||
* Gets the beans <code>EventSetDescriptor</code>s.
|
||||
*
|
||||
* @return An array of EventSetDescriptors describing the kinds of
|
||||
* events fired by this bean. May return null if the information
|
||||
* should be obtained by automatic analysis.
|
||||
*/
|
||||
// EventSetDescriptor[] getEventSetDescriptors();
|
||||
|
||||
/**
|
||||
* A bean may have a "default" event that is the event that will
|
||||
* mostly commonly be used by humans when using the bean.
|
||||
* @return Index of default event in the EventSetDescriptor array
|
||||
* returned by getEventSetDescriptors.
|
||||
* <P> Returns -1 if there is no default event.
|
||||
*/
|
||||
// int getDefaultEventIndex();
|
||||
|
||||
/**
|
||||
* Returns descriptors for all properties of the bean.
|
||||
* May return {@code null} if the information
|
||||
* should be obtained by automatic analysis.
|
||||
* <p>
|
||||
* If a property is indexed, then its entry in the result array
|
||||
* will belong to the {@link IndexedPropertyDescriptor} subclass
|
||||
* of the {@link PropertyDescriptor} class.
|
||||
* A client of the {@code getPropertyDescriptors} method
|
||||
* can use "{@code instanceof}" to check
|
||||
* whether a given {@code PropertyDescriptor}
|
||||
* is an {@code IndexedPropertyDescriptor}.
|
||||
*
|
||||
* @return an array of {@code PropertyDescriptor}s
|
||||
* describing all properties supported by the bean
|
||||
* or {@code null}
|
||||
*/
|
||||
// PropertyDescriptor[] getPropertyDescriptors();
|
||||
|
||||
/**
|
||||
* A bean may have a "default" property that is the property that will
|
||||
* mostly commonly be initially chosen for update by human's who are
|
||||
* customizing the bean.
|
||||
* @return Index of default property in the PropertyDescriptor array
|
||||
* returned by getPropertyDescriptors.
|
||||
* <P> Returns -1 if there is no default property.
|
||||
*/
|
||||
// int getDefaultPropertyIndex();
|
||||
|
||||
/**
|
||||
* Gets the beans <code>MethodDescriptor</code>s.
|
||||
*
|
||||
* @return An array of MethodDescriptors describing the externally
|
||||
* visible methods supported by this bean. May return null if
|
||||
* the information should be obtained by automatic analysis.
|
||||
*/
|
||||
// MethodDescriptor[] getMethodDescriptors();
|
||||
|
||||
/**
|
||||
* This method allows a BeanInfo object to return an arbitrary collection
|
||||
* of other BeanInfo objects that provide additional information on the
|
||||
* current bean.
|
||||
* <P>
|
||||
* If there are conflicts or overlaps between the information provided
|
||||
* by different BeanInfo objects, then the current BeanInfo takes precedence
|
||||
* over the getAdditionalBeanInfo objects, and later elements in the array
|
||||
* take precedence over earlier ones.
|
||||
*
|
||||
* @return an array of BeanInfo objects. May return null.
|
||||
*/
|
||||
// BeanInfo[] getAdditionalBeanInfo();
|
||||
|
||||
}
|
@@ -92,4 +92,25 @@ public class SubsystemChainingAuthenticationComponent extends AbstractChainingAu
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AuthenticationComponent getAuthenticationComponent(String instanceId)
|
||||
{
|
||||
ApplicationContext context = this.applicationContextManager.getApplicationContext(instanceId);
|
||||
if(context != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
AuthenticationComponent authenticationComponent = (AuthenticationComponent) context
|
||||
.getBean(sourceBeanName);
|
||||
return authenticationComponent;
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user