Spring annotation based authentication

Jan 1, 0001

a simple authentication mechanism for those that cannot be bother to set up spring security can be implemented using spring interceptors and an annotation. Spring interceptors and invoked before the controllers and are a great place to do authentication checking. The basic approach is

  1. create an interceptor
  2. check the method that will be executed for this request in the interceptor
  3. if the method has an annotation check login state for the request.

I’ll be demonstrating this concept for an API that does authentication using a parameter called “token” but it can be simply adapted to session based authentication mechanisms. First of all you’ll need the interceptor, create a class called AuthenticationInterceptor and extend the spring HandlerInterceptorAdapter class. You could also implement the HandlerInterceptor interface.

@Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        LoginRequired loginRequired = handlerMethod.getMethod().getAnnotation(LoginRequired.class);
        if (loginRequired == null) {
            return true;
        }

        String token = httpServletRequest.getParameter("token");

        if (StringUtils.isBlank(token)) {
            throw new MissingParameterException();
        }

        authenticationService.checkToken(token);

        return super.preHandle(httpServletRequest, httpServletResponse, handler);
    }

what’s going on here is that we get the method for the request from the handler object, and check for an annotation named LoginRequired. If it is not present than this action does not require any login checks so proceed with any other handlers in the chain. If there is an annotation ask the authenticationService to do some checks. I assume that the service will throw an exception if the token is invalid. Next we need the annotation itself. Create an the annotation with the content

@Target({ElementType.METHOD, ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        public @interface LoginRequired {
        }

Quite simple. The retention policy is important so that the interceptor can find the annotation. next annotate any controllers you need to be protected with @LoginRequired.

@RequestMapping(value = "/protected/controller")
@LoginRequired
public ResponseEntity<BaseResponse> controller() {
   ...
}