单位要做用户权限校验,使用token进行校验和单点登录,这是当时做的一个demo
拦截器配置类
实现WebConfigurer,增加@Configuration注解。老版本是要继承Adapter,现在都用实现接口的方式了。
配置类将拦截器注册进去,然后配置拦截规则。
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(myInterceptor);//注册拦截前端所有请求
interceptorRegistration.addPathPatterns("/**");//拦截前端所有请求
interceptorRegistration.excludePathPatterns("/user/login");//不拦截前端的请求
}
}
拦截器类
拦截器类实现HandlerInterceptor类
preHandle方法在请求处理之前进行调用(Controller方法调用之前)
postHandle请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
afterCompletion在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
/**
* 拦截器类
*/
@Component
public class MyInterceptor implements HandlerInterceptor {
//日志
private static Logger logger = LoggerFactory.getLogger(MyInterceptor.class);
//单点服务url
@Value("${token.tokenUrl}")
private String url;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
try {
logger.info("************************************进入拦截器**********************************");
//从前端请求中获取token 权限id 节点id
String token = request.getHeader("Authorization");
String needPermission = request.getHeader("needPermission");
logger.info("拦截器获取token ===== " + token);
//如果是用户身份是游客,则不需要登录 直接放行
if (StringUtils.isNotEmpty(needPermission)) {
if (!Boolean.valueOf(needPermission)) {
return true;
}
}
//如果没有Token为空,拦截
if (StringUtils.isEmpty(token)) {
logger.info("no token");
//给前端返回信息,由前端控制路由跳转,就不用后端做重定向到登录页
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put("code",CodeStatus.noAuthorization);
ajaxResult.put("msg","no token");
response.getOutputStream().write(JSONObject.toJSONString(ajaxResult).getBytes("utf-8"));
response.getOutputStream().flush();
return false;
}
request.setAttribute("userIdByToken", token);
//设置header
HttpClientUtil.setToken(token);
HttpClientUtil.setNeedPermission(needPermission);
//去单点登录服务验证token
String doPostWithHeader = HttpClientUtil.doPostWithHeader(1, url, "");
logger.debug("doPostWithHeader : " + doPostWithHeader);
//单点登录服务返回的内容
AjaxResult parseObject = JSONObject.parseObject(doPostWithHeader, AjaxResult.class);
int code = (int) parseObject.get("code");
if (CodeStatus.tokenCorrect == code) {//正确
logger.info("token check right and not timeout");
return true;
} else {
response.getOutputStream().write(JSONObject.toJSONString(parseObject).getBytes("utf-8"));
response.getOutputStream().flush();
return false;
}
} catch (Exception e) {
logger.error("exception : ", e);
response.getOutputStream().write(JSONObject.toJSONString(e).getBytes("utf-8"));
response.getOutputStream().flush();
return false;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle执行了。。。。。。。");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion执行了。。。。。。。");
}
}
Controller类
@RestController
public class EmptyController {
//这个接口是为了让用户进拦截器,去得到单点登录服务返回的不同的code值
@GetMapping("/goToInterceptor")
public AjaxResult A(){
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put("code",0);
ajaxResult.put("msg","token check right and not timeout");
return ajaxResult;
}
}
启动类
/**
* 启动程序
*
*/
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@EnableScheduling
@MapperScan("cn.com.taiji.*.mapper")
@ComponentScan({"cn.com.taiji.*.*"})
public class TaiPortalApplication {
public static void main(String[] args) {
SpringApplication.run(TaiPortalApplication.class, args);
System.out.println("===================启动成功======================");
}
}
资源拦截器
ViewControllerRegistry能设置页面跳转,不用进Controller,拦截到指定的地址,然后跳到指定页面,比如跳首页,跳错误页之类的。
/**
* 通用配置
*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
/**
* 首页地址
*/
@Value("${taiji.indexUrl}")
private String indexUrl;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
/**
* 默认首页的设置,当输入域名是可以自动跳转到默认指定的网页
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:" + indexUrl);
}
/**
* 静态资源文件映射配置
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
/** 文件上传路径 */
registry.addResourceHandler("/profile/**").addResourceLocations("file:" + Global.getProfile());
// 注意 :
// 1. addResourceHandler 参数可以有多个
// 2. addResourceLocations 参数可以是多个,可以混合使用 file: 和 classpath : 资源路径
// 3. addResourceLocations 参数中资源路径必须使用 / 结尾,如果没有此结尾则访问不到
// 映射到文件系统中的静态文件(应用运行时,这些文件无业务逻辑,但可能被替换或者修改)
registry.addResourceHandler("/repo/**").addResourceLocations("file:/tmp/");
// 映射到jar包内的静态文件(真正的静态文件,应用运行时,这些文件无业务逻辑,也不能被替换或者修改)
registry.addResourceHandler("/my-static/**").addResourceLocations("classpath:/my-static/");
}
}