Spring Boot过滤器与拦截器的安全认证实战从浅入深教程

Spring Boot使用过滤器和拦截器分别实现REST接口来做安全认证实战其实是比较牛X的,不管你同不同意,我反正是认同的,怎么说呢?​现在我作为23体验网的安全认证官,给你一个简易安全认证示例的开发实践,来了解下过滤器和拦截器的工作原理。Spring Boot过滤器与拦截器的安全认证实战从浅入深教程你知道吗?

我之前在许多文章也看到说过滤器(Filter)、拦截器(Interceptor)和监听器(Listener)这三者和Spring相关起来讲解,并以为过滤器(Filter)、拦截器(Interceptor)和监听器(Listener)是Spring供给的运用广泛的组件功用。这只是其中的一部分,另外一部分就是Spring Boot的安全认证实战。


可是严格来说,过滤器和监听器属于Servlet领域的API,和Spring没什么联系。

由于过滤器承继自javax.servlet.Filter接口,监听器承继自javax.servlet.ServletContextListener接口,只要拦截器承继的是org.springframework.web.servlet.HandlerInterceptor接口。

一、Spring Boot安全认证规划思路

有时分内外网调用API,Spring Boot过滤器与拦截器的安全认证实战从浅入深教程对安全性的要求不一样,许多情况下外网调用API的种种约束在内网底子没有必要,可是网关布置的时分,可能由于本钱和杂乱度等问题,内外网要调用的API会布置在一起。

package com.power.demo.controller.interceptor;

import com.power.demo.common.AppConst;
import com.power.demo.common.BizResult;
import com.power.demo.service.contract.AuthTokenService;
import com.power.demo.util.PowerLogger;
import com.power.demo.util.SerializeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
 * 认证token拦截器
 * */
@Component
public class AuthTokenInterceptor implements HandlerInterceptor {

    @Autowired
    private AuthTokenService authTokenService;

    /*
     * 请求执行前执行
     * */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        boolean handleResult = false;

        String token = request.getHeader(AppConst.AUTH_TOKEN);

        BizResult<String> bizResult = authTokenService.powerCheck(token);

        System.out.println(SerializeUtil.Serialize(bizResult));

        handleResult = bizResult.getIsOK();

        PowerLogger.info("auth token interceptor拦截结果:" + handleResult);

        if (bizResult.getIsOK() == true) {
            PowerLogger.info("auth token interceptor passed");
        } else {
            throw new Exception(bizResult.getMessage());
        }

        return handleResult;
    }

    /*
     * 请求结束执行
     * */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    /*
     * 视图渲染完成后执行
     * */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

完成REST接口的安全性,能够经过老练结构如Spring Security或许shiro搞定。

可是由于安全结构往往完成杂乱(我数了下Spring Security,洋洋洒洒大约有11个核心模块,shiro的源码代码量也比较惊人)一起可能要引入杂乱装备(能不能让人痛快一点),不利于中小团队的灵活快速开发、布置及问题排查。

许多团队自己造轮子完成安全认证,本文这个简易认证示例参考自我地点的前厂开发团队,能够以为是个依据token的安全认证效劳。

二、自定义过滤器

和Spring MVC类似,Spring Boot供给了许多servlet过滤器(Filter)可运用,并且它主动增加了一些常用过滤器,比方CharacterEncodingFilter(用于处理编码问题)、HiddenHttpMethodFilter(躲藏HTTP函数)、HttpPutFormContentFilter(form表单处理)、RequestContextFilter(恳求上下文)等。一般咱们还会自定义Filter完成一些通用功用,比方记载日志、判别是否登录、权限验证等。

1、自定义请求头

很简单,在request header增加自定义请求头authtoken:

加了@RequestHeader润饰的authtoken字段就能够在swagger这样的结构下显示出来。调用后,能够依据http工具看到请求头,本文示例是authtoken(和某些结构的token区分隔):

2、完成Filter

Filter接口共有三个办法,即init,doFilter和destory,看到称号就大约知道它们主要用途了,一般咱们只要在doFilter这个办法内,对Http请求进行处理:

@Order(1)
@WebFilter(urlPatterns = {"/api/v1/goods/*", "/api/v1/userinfo/*"})
public class AuthTokenFilter implements Filter {

留意,Filter这样的东西,我以为从实践分层视点,大都处理的还是体现层偏多,不主张在Filter中直接运用数据拜访层Dao,尽管这样的代码一两年前我在许多老古董项目中看到过许屡次,并且<<spring< span="">实战>>的书里也有这样写的先例。发动运用后,调用接口就能够看到阻拦器阻拦的作用了。大局一致的反常管理GlobalExceptionHandler捕获反常。

import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import java.util.List;

@Configuration
@Component
public class RestFilterConfig {

    @Autowired
    private AuthTokenFilter filter;

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(filter);

        //设置(模糊)匹配的url
        List<String> urlPatterns = Lists.newArrayList();
        urlPatterns.add("/api/v1/goods/*");
        urlPatterns.add("/api/v1/userinfo/*");
        registrationBean.setUrlPatterns(urlPatterns);

        registrationBean.setOrder(1);
        registrationBean.setEnabled(true);

        return registrationBean;
    }
}

在Java Web下经过自定义过滤器Filter或许阻拦器Interceptor装备urlPatterns,能够完成对特定匹配的API进行安全认证,比方匹配一切API、匹配某个或某几个API等,可是有时分这种匹配形式对开发人员相对不行友爱。

猜你喜欢

转载自blog.csdn.net/du_23tiyanwang/article/details/80614248
今日推荐