<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
import com.leyou.auth.entity.UserInfo;
import com.leyou.auth.utils.JwtUtils;
import com.leyou.common.utils.CookieUtils;
import com.leyou.item.client.UserClient;
import com.leyou.item.config.JwtProperties;
import com.leyou.user.pojo.Menu;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author huang
*/
@EnableConfigurationProperties(JwtProperties.class)
public class LoginInterceptor extends HandlerInterceptorAdapter {
public static final String KEY_PREFIX = "user:id:permission:";
@Autowired
private JwtProperties props;
@Autowired
static private StringRedisTemplate redisTemplate;
@Autowired
private UserClient userClient;
//定义一个线程域,存放登录的对象
private static final ThreadLocal<UserInfo> t1 = new ThreadLocal<>();
public LoginInterceptor() {
super();
}
public LoginInterceptor(JwtProperties props,StringRedisTemplate redisTemplate,UserClient userClient) {
this.props = props;
this.redisTemplate=redisTemplate;
this.userClient=userClient;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//查询Token
String token = CookieUtils.getCookieValue(request, props.getCookieName());
if (StringUtils.isBlank(token)) {
//用户未登录,返回401,拦截
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
//用户已登录,获取用户信息
try {
UserInfo userInfo = JwtUtils.getUserInfo(props.getPublicKey(), token);
//从redis获取用户权限
String key = KEY_PREFIX + userInfo.getId();
String permission = this.redisTemplate.opsForValue().get(key);
if(StringUtils.isEmpty(permission)){
//redis没有则从数据库查按钮权限,存入redis
List<Menu> list=this.userClient.queryPermsByUserId(userInfo.getId(),2L);
StringBuffer sb=new StringBuffer();
for(Menu m:list){
appendAllPermission(sb, m);
sb.append(m.getPerms()+",");
}
sb.deleteCharAt(sb.length()-1);
this.redisTemplate.opsForValue().set(key, sb.toString(), 30, TimeUnit.MINUTES);//权限缓存30分钟
}
//放入线程域中
t1.set(userInfo);
return true;
} catch (Exception e) {
//抛出异常,未登录
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
}
private void appendAllPermission(StringBuffer sb, Menu m) {
for(Menu menu:m.getItems()){
sb.append(menu.getPerms()+",");
appendAllPermission(sb,menu);
}
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//过滤器完成后,从线程域中删除用户信息
t1.remove();
}
/**
* 获取登陆用户
* @return
*/
public static UserInfo getLoginUser() {
return t1.get();
}
public static String getLoginUserPermission() {
UserInfo userInfo =LoginInterceptor.getLoginUser();
String key = LoginInterceptor.KEY_PREFIX + userInfo.getId();
return redisTemplate.opsForValue().get(key);
}
}
import com.leyou.item.client.UserClient;
import com.leyou.item.filter.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author bystander
* @date 2018/10/3
*/
@Configuration
@EnableConfigurationProperties(JwtProperties.class)
public class MvcConfig implements WebMvcConfigurer {
@Autowired
private JwtProperties props;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private UserClient userClient;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//配置登录拦截器
registry.addInterceptor(new LoginInterceptor(props,redisTemplate,userClient)).addPathPatterns("/**");
}
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 类似shiro的权限注解
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Requirespermissions{
String value();
}
import com.leyou.item.filter.LoginInterceptor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
/**
* 权限处理,切面处理类
*
* @author huang
*/
@Aspect
@Component
public class PermissionsAspect {
@Pointcut("@annotation(com.leyou.aspect.Requirespermissions)")
public void Requirespermissions() {
}
@Before("Requirespermissions()")
public void Requirespermissions(JoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Requirespermissions requirespermissionsFilter = signature.getMethod().getAnnotation(Requirespermissions.class);
//权限校验
String loginUserPermission = LoginInterceptor.getLoginUserPermission();
if(!loginUserPermission.contains(requirespermissionsFilter.value())){
throw new Exception();//抛出异常中断请求
}
}
}