31

I have some Spring RESTful (RestControllers) web services with no web.xml and I am using Spring boot to start the services.

I want to add authorization layer for the web services and wanted to route all the http requests to one front controller before actually calling the web service itself. (I have a code to simulate sessions behavior at the autherisation layer, to validate a user based on a generated key that I send with each of the httpRequest from the client).

Is there any Standard Spring solution on routing all the requests to a filter /front controller?

Thanks in advance, Praneeth

Edit: Adding my code

Controller: `

@RestController public class UserService { UserDAO userDAO = new UserDAO(); @RequestMapping(value="/login", method = RequestMethod.POST) @LoginRequired public String login(@RequestParam(value="user_name") String userName, @RequestParam(value="password") String password, HttpServletRequest request){ return userDAO.login(userName, password); } }` 

Interceptor:

`

public class AuthenticationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("In Interceptor"); //return super.preHandle(request, response, handler); return true; } @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("---method executed---"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---Request Completed---"); } } 

`

Interface. `

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

`

1
  • 1
    Set tocken or ID in request header and validate it. Commented Jun 21, 2018 at 9:54

6 Answers 6

31

Following steps can be taken to implement the interceptor with Spring:

  • Implement an interceptor class extending HandlerInterceptorAdapter class. Following is how the code could look like:

    public class LoginInterceptor extends HandlerInterceptorAdapter { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception { // TODO Auto-generated method stub } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; String emailAddress = request.getParameter("emailaddress"); String password = request.getParameter("password"); if(StringUtils.isEmpty(emailAddress) || StringUtils.containsWhitespace(emailAddress) || StringUtils.isEmpty(password) || StringUtils.containsWhitespace(password)) { throw new Exception("Invalid User Id or Password. Please try again."); } return true; } } 
  • Implement an AppConfig class or add the addInterceptors in one of the existing Configuration class. Note the path pattern specified with the LoginInterceptor instance

    @Configuration public class AppConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/account/login"); } } 
  • Implement the controller method such as following:

    @Controller @RequestMapping("/account/login") public class LoginController { @RequestMapping(method = RequestMethod.GET) public String login() { return "login"; } } 
Sign up to request clarification or add additional context in comments.

2 Comments

How do you know you get a HandlerMethod passed to your LoginInterceptor?
WebMvcConfigurerAdapter is now deprecated. Implement WebMvcConfigurer instead.
12

here an example of Interceptor :

public class AuthenticationInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 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); } @Override public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("---method executed---"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("---Request Completed---"); } 

We can create an annotation :

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

And then on controller, we had this annotation :

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

This is just a template/example to give you an idea. I hope this will help you.

3 Comments

Hello Pracede, Thanks for the reply. But this does'nt seem to be working. Should'nt we some where specify that Interceptor is being used(like any annotation or in any xml file). I've implemented the above logic but is not working. I've attached my code in the edit space of the question. I would be greatly thankful to you if you could help me in this
@PraneethReddy You need to override addInterceptors method in WebMvcConfigurer. Also annotate your class with @Configuration
What's the point of the annotation if you have add the interceptor?
4

There is a default solution for such things. spring security. And you will just have to implement something like:

@Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .formLogin() .loginPage("/login") .failureUrl("/login?error") .usernameParameter("email") .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/") .permitAll(); } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(userDetailsService) .passwordEncoder(new BCryptPasswordEncoder()); } } 

the dependency for it is:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 

Comments

4

After Spring 5 : Implementation should be like this: We should have a class that implements HandlerInterceptor:

 public class CustomInterceptor implements HandlerInterceptor { } 

Then we can register this interceptor by a class that implements WebMvcConfigurer and override the method addInterceptors

public class ServiceInterceptorAppConfig implements WebMvcConfigurer { @Autowired CustomInterceptor customInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(customInterceptor); } } 

Comments

3

You should add this to regsiter your interceptor

@Configuration public class MyConfiguration extends WebMvcConfigurerAdapter { @Bean AuthenticationInterceptor getAuthenticationInterceptor() { return new AuthenticationInterceptor(); } @Override public void addInterceptors (InterceptorRegistry registry) { registry.addInterceptor(getAuthenticationInterceptor()); } } 

1 Comment

@Component public class LoginInterceptor extends HandlerInterceptorAdapter{ ............} i.e Adding Component annotation over LoginInterceptor helped me
0

If you looking for simple answer for spring boot application..

public class HttpInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // do something here. return true; } } 

and

@Configuration public class AppConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HttpInterceptor()); // registry.addInterceptor(new HttpInterceptor()).addPathPatterns("/account/login"); you can add specific end point as well. } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.