Custom Annotation To Handle Authorisation In Micronaut AOP Tutorial
Overview:
- Creating custom annotation
- Creating component in Micronaut
- Creation a configuration and middleware(Interceptor) in Micronaut
- Basic of Aspect and usage in Micronaut
Micronaut is the web framework, Its features similar to spring boot also this framework is light weight, low memory foot print, and quick start up time, as we know solve cold start up time in few serverless provider like AWS lambda.
What is Aspect In Micronaut ?
Aspects are cross cutting concerns like logging, security in different layers for the ease of code maintenance .
Dependency required
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-aop</artifactId>
</dependency>
STEP 1 : Lets create an annotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Around
@Type(AuthInterceptor.class)
@Internal
public @interface Auth {
}
We use @Auth as annotation to Authorize our request, In our Application. So the Annotation target is method level, and it is retained during runtime, @Type annotation tells what logic to be executed when the annotation is used.
Step 2 : Lets Create a file which actually implement logic of authorization.
@Singleton
public class AuthService {
public User verify(String token) {
//TODO:Add you logic required used for Authorization
return new User("id","username");
}
}
Usually we write the service class to separate the logic, so can be used without rewriting again and again, i haven't implemented logic, as everyone's need is different.
Step 3 : Aspect file which acts as middleware which intercept the the request and authorize and proceed
public class AuthInterceptor implements MethodInterceptor<HttpRequest<Object>,Object> {
@Inject
AuthService service;
@Override
public Object intercept(MethodInvocationContext<HttpRequest<Object>, Object> context) {
context.getParameterValueMap().forEach((name, value) -> {
if(value instanceof HttpRequest) {
HttpRequest<Object> request = (HttpRequest<Object>) value;
String token = request.getHeaders().get("Auth");
if(token == null || token.isEmpty()) {
throw new AuthException("Need Authorization token");
}
//this is used if want to add user details
request.setAttribute("session",service.verifyToken(token));
}
} );
return context.proceed ();
}
}
At the above step, I am reading the Http request, and fetching the Authorization token, and verifying the token using the AuthService
which is injected at during declaration.
Step 4 : Usage of the annotation to authorize the request
@Introspected
@Controller("/users")
public class AuthorizeController {
@Inject
private AuthService authService;
@Get("/verify")
@Auth
public Users verify(HttpRequest<Object> request) {
User user = (User) request.getAttribute("session").get();
return user;
}
}
So this is the normal Controller Micronaut, At the top `@Auth` is used to intercept the request, which will Authorize the request. and to read the user details I am using ` User user = (User) request.getAttribute("session").get(); ` code to get the details inside my controller.