2 changed files with 162 additions and 0 deletions
@ -0,0 +1,81 @@
@@ -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(); |
||||
} |
||||
} |
||||
@ -0,0 +1,81 @@
@@ -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; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue