Spring MVC 如何为Spring RESTful Web服务创建Spring Interceptor

pokxtpni  于 2023-05-18  发布在  Spring
关注(0)|答案(6)|浏览(243)

我有一些没有web.xml的Spring RESTful(RestControllers)Web服务,我正在使用Sping Boot 启动服务。
我想为web服务添加授权层,并想在实际调用web服务本身之前将所有http请求路由到一个前端控制器。(我有一个代码来模拟认证层的会话行为,根据我从客户端发送的每个httpRequest所生成的密钥来验证用户)。
是否有任何标准的Spring解决方案将所有请求路由到过滤器/前端控制器?
先谢谢你,普兰尼斯
编辑:添加我的代码
控制器:`

@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);
    }
}`

拦截器:

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---");
    }
}


接口。`

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

k2arahey

k2arahey1#

使用Spring实现拦截器可以采取以下步骤:

  • 实现一个扩展HandlerInterceptorAdapter类的拦截器类。下面是代码的样子:
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;
    }

}
  • 实现一个AppConfig类或在一个现有的Configuration类中添加addInterceptor。请注意使用LoginInterceptor示例指定的路径模式
@Configuration  
public class AppConfig extends WebMvcConfigurerAdapter  {  

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/account/login");
    }
}
  • 执行控制器方法,如下所示:
@Controller
@RequestMapping("/account/login")
public class LoginController {

    @RequestMapping(method = RequestMethod.GET)
    public String login() {
        return "login";
    }
}
0s0u357o

0s0u357o2#

下面是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---");
    }

我们可以创建一个注解:

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

然后在控制器上,我们有这样的注解:

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

这只是一个模板/例子,给予你一个想法。我希望这对你有帮助。

guykilcj

guykilcj3#

这类事情有一个默认的解决方案。Spring的安全你只需要实现如下内容:

@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());
    }
}

它的依赖关系是:

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

piztneat4#

Spring5:实现应该是这样的:我们应该有一个实现HandlerInterceptor的类:

public class CustomInterceptor implements HandlerInterceptor {
    }

然后,我们可以通过实现WebMvcConfigureer的类注册这个拦截器,并覆盖addInterceptor方法

public class ServiceInterceptorAppConfig implements WebMvcConfigurer {
  @Autowired
  CustomInterceptor customInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(customInterceptor);
  }
}
hrysbysz

hrysbysz5#

你应该添加这个来注册你的拦截器

@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    AuthenticationInterceptor getAuthenticationInterceptor() {
        return new AuthenticationInterceptor();
    }

    @Override
    public void addInterceptors (InterceptorRegistry registry) {
        registry.addInterceptor(getAuthenticationInterceptor());

    }
}
ct3nt3jp

ct3nt3jp6#

如果您正在寻找Sping Boot 应用程序的简单答案..

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

@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.
    }
}

相关问题