public List<MyObject> find( Authentication auth )
//read details off the authentication object.
OAuth2AuthenticationDetails oauthDetails= (OAuth2AuthenticationDetails) auth.getDetails();
HashMap<String, Object> additionalInformationMap = ( HashMap<String, Object> )oauthDetails.getDecodedDetails();
I currently have a small bit of code in my controller that reads additional information stored in a JWT token.
Preferably I would not like to write this code in multiple controller methods- chances are it would be peppered throughout the codebase.
Is there a better way of doing this in Spring that isn't in the controller. e.g. can I extend the Authentication object in a filter or something and add that extra data to a public method on the extended object?
Edit. from reading around, it appears that AOP potentially would solve this problem. Just not sure where to start
Define an annotation that can be applied to methods and classes. If it is applied to a class, the annotation simply cascades and applies to all methods in the class.
package com.perfectcomputersolutions.pos.annotation;
import org.springframework.stereotype.Component;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Component
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoNullArgs {
}
Then create a class with an advice (method to apply) to a series of point cuts (locations to apply the actual advice). Note. This is an example implemented in Groovy that merely checks that all arguments are not null. However, you can change the body of the method to do whatever you want. Once you have the args
array, those are the values that you can cast to the the expected type.
package com.perfectcomputersolutions.pos.aspect
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.reflect.CodeSignature
import org.springframework.core.annotation.Order
import org.springframework.stereotype.Component
@Aspect
@Order(0)
@Component
class NoNullArgsAspect {
// Use this if writing in Java.
// omitting the getMetaClass call is only for Groovy
// @Before(
// value = "@within(com.perfectcomputersolutions.pos.annotation.NoNullArgs) || @annotation(com.perfectcomputersolutions.pos.annotation.NoNullArgs)"
// )
@Before(
value = "!execution(* *.getMetaClass(..)) && @within(com.perfectcomputersolutions.pos.annotation.NoNullArgs) || @annotation(com.perfectcomputersolutions.pos.annotation.NoNullArgs)"
)
void requireNotNull(JoinPoint jp) {
def method = (CodeSignature) jp.signature
def types = method.parameterTypes
def names = method.parameterNames
def args = jp.args
for (int i = 0; i < types.length; i++)
Objects.requireNonNull(args[i], "Parameter ${names[i]} must not be null" as String)
}
}
- See original post.
- See Spring AOP Docs