springboot自定义注解进行登录权限的验证

springboot自定义注解进行登录权限的验证

本人以前没有写过这种的拦截,经过查资料和收集前辈们的经验,自己实现后的一些心得想分享给大家,希望大家不喜勿喷.

这里涉及到拦截器,先简单的说明一下拦截器:

拦截器在我们项目中经常使用,最简单 的就是用来判断是否登录.要实现拦截器需要完成两个步骤.

1.创建我们自己的拦截器类并且实现HandlerInterceptor接口 或者HandlerInterceptorAdapter类

2.重写preHandle方法(简单的解释一下拦截器方法的执行顺序)

我们可以在这个方法里面加上我们自己的逻辑,比如判断他是否已经登录

springboot自定义注解进行登录权限的验证_第1张图片

如果被我们拦截以后,不能通过的,请求,我们可以这样编写返回值

springboot自定义注解进行登录权限的验证_第2张图片

 

这两步做完以后,我们只是创建了一个自己的拦截器,但是我们需要把他加到springboot的拦截器中,这时我们需要创建一个配置类,用于把我们自己的拦截器注册到Springboot中,实现WebMvcConfigurer

并且重写addInterceptors方法,

springboot自定义注解进行登录权限的验证_第3张图片

简单解释一下, addInterceptor 中添加自己创建的拦截器,addPathPatterns表示要拦截的请求路径,addPathPatterns("/**")对所有请求都拦截,excludePathPatterns表示要排除的请求路径

下面是WebMvcConfigurer 常重写的方法和注解:

springboot自定义注解进行登录权限的验证_第4张图片

 

 

一般我们通过创建一个自定义的注解,来配置我们的请求,列如,我们的请求方法上有我们定义的注解需要进行登录,没有的不需要(其实我们上面的拦截器也能做到这一点).判断是否有注解需要在我们定义的拦截器中判断.

springboot自定义注解进行登录权限的验证_第5张图片

 

自定义注解只需要一步:

springboot自定义注解进行登录权限的验证_第6张图片

就这样,其实我们一般都需要拦截器+注解来相互配合,通过查找请求的路径是否存在该注解来进行判断

注解的解释:

@Target 注解

springboot自定义注解进行登录权限的验证_第7张图片

@Retention 注解

springboot自定义注解进行登录权限的验证_第8张图片

@Inherited(可以不用)

@Documented

上面就是,我们可以通过自定义注解来拦截请求,查看是否需要登录的整体思路

 

下面试具体代码

注解类:

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Inherited;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* 登录权限的注解

* @author Administrator

*

*/

@Target(value = { ElementType.TYPE,ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface LoginInterceptor {

}

创建自己的拦截器类:

import java.io.PrintWriter;

import java.lang.reflect.Method;

import java.util.List;

import java.util.Map;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.druid.util.StringUtils;

import com.alibaba.fastjson.JSONObject;

import com.cpp.epsserv.config.RedisClient;

import com.cpp.epsserv.config.SpringContextUtil;

import com.cpp.epsserv.encapsulation.whcgpt.getData.SignUtils;

import com.cpp.epsserv.mapper.IntLoginMapper;

import com.cpp.epsserv.model.IntLogin;

import com.cpp.epsserv.model.IntLoginExample;

 

public class SecurityInterceptor extends HandlerInterceptorAdapter {

 

//参数签名认证信息(具体使用签名认证)

private String httpHeaderSign = "sign";

//用户名称

private String httpHeaderName = "username";

//鉴权失败后返回的HTTP错误码,默认为401

private int unauthorizedErrorCode = HttpServletResponse.SC_UNAUTHORIZED;

// 获取到redis

private static RedisClient redisClient = SpringContextUtil.getBean(RedisClient.class);

private static IntLoginMapper loginMapper = SpringContextUtil.getBean(IntLoginMapper.class);

//在调用方法之前调用

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//将handler强转化为handlermethod

HandlerMethod handlerMethod = (HandlerMethod)handler;

//从方法处理器中获取要调用的方法

Method method = handlerMethod.getMethod();

//获取方法上的LoginInterceptor注解

LoginInterceptor loginInterceptor = method.getAnnotation(LoginInterceptor.class);

if (null == loginInterceptor) {

//如果注解为null,说明此方法没有注解直接放过

return true;

}

//从请求头中获取验证信息

String sign = request.getHeader(httpHeaderSign);

String username = request.getHeader(httpHeaderName);

IntLoginExample example = new IntLoginExample();

example.createCriteria().andUsernameEqualTo(username);

List loginList = loginMapper.selectByExample(example);

if (null == loginList || loginList.size()<0) {

JSONObject jsonObject = new JSONObject();

PrintWriter out = null;

try {

response.setStatus(unauthorizedErrorCode);

response.setContentType("application/json");

response.setCharacterEncoding("UTF-8");

jsonObject.put("code", response.getStatus());

jsonObject.put("failreason", "登录账号或密码错误");

out = response.getWriter();

out.println(jsonObject);

return false;

} catch (Exception e) {

e.printStackTrace();

}finally {

if (null != out) {

out.flush();

out.close();

}

}

}

ServletInputStream inputStream = request.getInputStream();

String jsonString = IOUtils.toString(inputStream);

Map mapMembers = redisClient.getMapMembers(username);

if (null == mapMembers || mapMembers.isEmpty()) {

JSONObject jsonObject = new JSONObject();

PrintWriter out = null;

try {

response.setStatus(unauthorizedErrorCode);

response.setContentType("application/json");

response.setCharacterEncoding("UTF-8");

jsonObject.put("code", response.getStatus());

jsonObject.put("failreason", "登录超时,请重新登录");

out = response.getWriter();

out.println(jsonObject);

return false;

} catch (Exception e) {

e.printStackTrace();

}finally {

if (null != out) {

out.flush();

out.close();

}

}

}

String token = String.valueOf(mapMembers.get("token"));

String localSign = SignUtils.Sign(token+jsonString,loginList.get(0).getPassword());

if (!localSign.equals(sign)) {

JSONObject jsonObject = new JSONObject();

PrintWriter out = null;

try {

response.setStatus(unauthorizedErrorCode);

response.setContentType("application/json");

response.setCharacterEncoding("UTF-8");

jsonObject.put("code", response.getStatus());

jsonObject.put("failreason", "登录验证信息有误");

out = response.getWriter();

out.println(jsonObject);

return false;

} catch (Exception e) {

e.printStackTrace();

}finally {

if (null != out) {

out.flush();

out.close();

}

}

}

return true;

}

 

}

将我们自定义的拦截器加到springmvc的拦截器中(拦截器是依赖于web框架的)

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**

* 拦截器:判断是否登录

* @author Administrator

*

*/

@Configuration

public class WebAppConfiguration extends WebMvcConfigurerAdapter{

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new SecurityInterceptor()).addPathPatterns("/**");

}

}

2019/01/14 10:25

 

你可能感兴趣的:(springboot自定义注解进行登录权限的验证)