SEC-716: Default (non-web) AuthenticationDetailsSource implementation.

This commit is contained in:
Luke Taylor 2008-03-18 18:45:38 +00:00
parent c9ff912b2f
commit f8d855f1a2
2 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1,81 @@
package org.springframework.security.ui;
import java.io.Serializable;
/**
* A holder of the context as a string.
*
* @author Ruud Senden
* @since 2.0
*/
public class AuthenticationDetails implements Serializable {
//~ Instance fields ================================================================================================
private String context;
//~ Constructors ===================================================================================================
/**
* Constructor.
*
* @param context that the authentication request is initiated from
*/
public AuthenticationDetails(Object context) {
this.context = context==null?"":context.toString();
doPopulateAdditionalInformation(context);
}
protected AuthenticationDetails() {
throw new IllegalArgumentException("Cannot use default constructor");
}
//~ Methods ========================================================================================================
/**
* Provided so that subclasses can populate additional information.
*
* @param request that the authentication request was received from
*/
protected void doPopulateAdditionalInformation(Object context) {}
public boolean equals(Object obj) {
if (obj instanceof AuthenticationDetails) {
AuthenticationDetails rhs = (AuthenticationDetails) obj;
if ((context == null) && (rhs.getContext() != null)) {
return false;
}
if ((context != null) && (rhs.getContext() == null)) {
return false;
}
if (context != null) {
if (!context.equals(rhs.getContext())) {
return false;
}
}
return true;
}
return false;
}
/**
* Indicates the context.
*
* @return the address
*/
public String getContext() {
return context;
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString() + ": ");
sb.append("Context: " + this.getContext());
return sb.toString();
}
}

View File

@ -0,0 +1,81 @@
package org.springframework.security.ui;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.springframework.security.ui.AuthenticationDetailsSource;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Base implementation of {@link AuthenticationDetailsSource}.
* <p>
* By default will create an instance of <code>AuthenticationDetails</code>.
* Any object that accepts an <code>Object</code> as its sole constructor can
* be used instead of this default.
* </p>
*
* @author Ruud Senden
* @since 2.0
*/
public class AuthenticationDetailsSourceImpl implements AuthenticationDetailsSource {
//~ Instance fields ================================================================================================
private Class clazz = AuthenticationDetails.class;
//~ Methods ========================================================================================================
public Object buildDetails(Object context) {
try {
Constructor constructor = getFirstMatchingConstructor(context);
return constructor.newInstance(new Object[] { context });
} catch (NoSuchMethodException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (InvocationTargetException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (InstantiationException ex) {
ReflectionUtils.handleReflectionException(ex);
} catch (IllegalAccessException ex) {
ReflectionUtils.handleReflectionException(ex);
}
return null;
}
/**
* Return the first matching constructor that can take the given object
* as an argument. Please note that we cannot use
* getDeclaredConstructor(new Class[]{object.getClass()})
* as this will only match if the constructor argument type matches
* the object type exactly (instead of checking whether it is assignable)
*
* @param object the object for which to find a matching constructor
* @return a matching constructor for the given object
* @throws NoSuchMethodException if no matching constructor can be found
*/
private Constructor getFirstMatchingConstructor(Object object) throws NoSuchMethodException {
Constructor[] constructors = clazz.getDeclaredConstructors();
Constructor constructor = null;
for (int i = 0; i < constructors.length; i++) {
Class[] parameterTypes = constructors[i].getParameterTypes();
if (parameterTypes.length == 1 && (object == null || parameterTypes[i].isInstance(object))) {
constructor = constructors[i];
break;
}
}
if (constructor == null) {
if (object == null) {
throw new NoSuchMethodException("No constructor found that can take a single argument");
} else {
throw new NoSuchMethodException("No constructor found that can take a single argument of type " + object.getClass());
}
}
return constructor;
}
public void setClazz(Class clazz) {
Assert.notNull(clazz, "Class required");
this.clazz = clazz;
}
}