文章目录

  • 背景
  • 注解配置filter
  • 硬编码注册filter
  • 跨域说明
  • 方式2.配置注解


背景

web验证授权合法的一般分为下面几种

  • 1使用session作为验证合法用户访问的验证方式
  • 使用自己实现的token
  • 使用OCA标准

在使用API接口授权验证时,token是自定义的方式实现起来不需要引入其他东西,关键是简单实用。

合法登陆后一般使用用户UID+盐值+时间戳使用多层对称加密生成token并放入分布式缓存中设置固定的过期时间长(和session的方式有些相同),这样当用户访问时使用token可以解密获取它的UID并据此验证其是否是合法的用户。

#springboot中实现filter

  • 一种是注解filter
  • 一种是显示的硬编码注册filter

先有filter

import javax.servlet.annotation.WebFilter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import springfox.documentation.spring.web.json.Json;

import com.alibaba.fastjson.JSON;
 
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



/***************
 * token验证拦截
 * @author bamboo zjcjava@163.com
 * @time 2017-08-01
 */
@Component
//@WebFilter(urlPatterns = { "/api/v/*" }, filterName = "tokenAuthorFilter")
public class TokenAuthorFilter implements Filter {

	private static Logger logger = LoggerFactory
			.getLogger(TokenAuthorFilter.class);

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse rep = (HttpServletResponse) response;

		//设置允许跨域的配置
		// 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
		rep.setHeader("Access-Control-Allow-Origin", "*");
		// 允许的访问方法
		rep.setHeader("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE, PATCH");
		// Access-Control-Max-Age 用于 CORS 相关配置的缓存
		rep.setHeader("Access-Control-Max-Age", "3600");
		rep.setHeader("Access-Control-Allow-Headers","token,Origin, X-Requested-With, Content-Type, Accept");


		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		String token = req.getHeader("token");//header方式
		ResultInfo resultInfo = new ResultInfo();
		boolean isFilter = false;
		
			
		String method = ((HttpServletRequest) request).getMethod();
		if (method.equals("OPTIONS")) {
			rep.setStatus(HttpServletResponse.SC_OK);
		}else{
			
			
			if (null == token || token.isEmpty()) {
				resultInfo.setCode(Constant.UN_AUTHORIZED);
				resultInfo.setMsg("用户授权认证没有通过!客户端请求参数中无token信息");
			} else {
				if (TokenUtil.volidateToken(token)) {
					resultInfo.setCode(Constant.SUCCESS);
					resultInfo.setMsg("用户授权认证通过!");
					isFilter = true;
				} else {
					resultInfo.setCode(Constant.UN_AUTHORIZED);
					resultInfo.setMsg("用户授权认证没有通过!客户端请求参数token信息无效");
				}
			}
			if (resultInfo.getCode() == Constant.UN_AUTHORIZED) {// 验证失败
				PrintWriter writer = null;
				OutputStreamWriter osw = null;
				try {
					osw = new OutputStreamWriter(response.getOutputStream(),
							"UTF-8");
					writer = new PrintWriter(osw, true);
					String jsonStr = JSON.toJSONString(resultInfo);
					writer.write(jsonStr);
					writer.flush();
					writer.close();
					osw.close();
				} catch (UnsupportedEncodingException e) {
					logger.error("过滤器返回信息失败:" + e.getMessage(), e);
				} catch (IOException e) {
					logger.error("过滤器返回信息失败:" + e.getMessage(), e);
				} finally {
					if (null != writer) {
						writer.close();
					}
					if (null != osw) {
						osw.close();
					}
				}
				return;
			}
			
			if (isFilter) {
			logger.info("token filter过滤ok!");
			chain.doFilter(request, response);
			}
		}
			
		
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {

	}

}

注解配置filter

加上如下配置则启动时会根据注解加载此filter
@WebFilter(urlPatterns = { “/api/*” }, filterName = “tokenAuthorFilter”)

硬编码注册filter

在application.java中加入如下代码

//注册filter
    @Bean  
    public FilterRegistrationBean  filterRegistrationBean() {  
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();  
        TokenAuthorFilter tokenAuthorFilter = new TokenAuthorFilter();  
        registrationBean.setFilter(tokenAuthorFilter);  
        List<String> urlPatterns = new ArrayList<String>();  
        urlPatterns.add("/api/*");
        registrationBean.setUrlPatterns(urlPatterns);  
        return registrationBean;  
    }

以上两种方式都可以实现filter

跨域说明

springboot可以设置全局跨域,但是对于filter中的拦截地址并不其中作用,因此需要在dofilter中再次设置一次

区局设置跨域方式如下
##方式1.在application.java中加入如下代码

//跨域设置
	private CorsConfiguration buildConfig() {  
        CorsConfiguration corsConfiguration = new CorsConfiguration();  
        corsConfiguration.addAllowedOrigin("*");  
        corsConfiguration.addAllowedHeader("*");  
        corsConfiguration.addAllowedMethod("*");  
        
        
        
        return corsConfiguration;  
    }  
      
    /** 
     * 跨域过滤器 
     * @return 
     */  
    @Bean  
    public CorsFilter corsFilter() {  
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
        source.registerCorsConfiguration("/**", buildConfig()); // 4  
        return new CorsFilter(source);  
    }

方式2.配置注解

必须集成WebMvcConfigurerAdapter类

/**********
 * 跨域 CORS:使用 方法3
 * 方法:
	1服务端设置Respone Header头中Access-Control-Allow-Origin
	2配合前台使用jsonp
	3继承WebMvcConfigurerAdapter 添加配置类
 * @author xialeme
 *
 */
@Configuration  
public class CorsConfig extends WebMvcConfigurerAdapter{  
  
   /* @Override  
    public void addCorsMappings(CorsRegistry registry) {  
        registry.addMapping("/**")  
                .allowedOrigins("*")  
                .allowCredentials(true)  
                .allowedMethods("GET", "POST", "DELETE", "PUT")  
                .maxAge(3600);  
    }  */
  
	private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1
        corsConfiguration.addAllowedHeader("*"); // 2
        corsConfiguration.addAllowedMethod("*"); // 3
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig()); // 4
        return new CorsFilter(source);
    }
  
    
}