网络安全是如此重要,项目开发中我们经常会使用Spring Security / Shiro 实现安全控制,即对访问人员的认证和授权。移动互联网的发展出现了多端访问(Android、IOS、小程序、Web) 和对高并发、高可用、分布式的要求,对于传统Web开发,服务器端会维护用户登录信息,对高并发将是一个严重的性能制约。
1.基于多端访问,服务端无状态(stateless) 要求,JWT 是一种非常优秀的解决方案;
2.后台管理接口为了安全一定要有权限校验,防止客户端用户非法破坏数据。
1.RequiredPermission.java 权限注解定义
package com.vincent;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiredPermission {
String value();
}
2.PermissionInterceptor.java 权限拦截器
public class PermissionInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/*
*从request Headers 中获取用户身份信息,如token
* 获取用户相关权限信息
*/
List perms = Arrays.asList("perm:read","perm:write");
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod)handler;
RequiredPermission permission = handlerMethod.getMethod().getDeclaredAnnotation(RequiredPermission.class);
if(permission != null){
if(perms.contains(permission.value())){
return true;
}
else{
throw new IllegalAccessException("非法访问");
}
}
}
return true;
}
}
3.WebMvcConfig.java 注入拦截器配置
@Configuration
public static class WebMvcConfig implements WebMvcConfigurer{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new PermissionInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}
4.HelloController.java
package com.vincent.controller;
import com.vincent.RequiredPermission;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
@RequiredPermission("perm:err")
public String hello(String name){
return "hello " + name;
}
@GetMapping("/test-read")
@RequiredPermission("perm:read")
public String testRead(){
return "test read success!";
}
@GetMapping("/login")
public String login(){
return "login success";
}
}
1.访问 http://localhost:8080/login
2.访问 http://localhost:8080/test-read
3.访问 http://localhost:8080/hello
1.HandlerInterceptor 拦截器是在DispatcherServlet 后执行的,故对于自定义的Servlet 将不起作用,但是使用SpringMVC 的Controller 已足够我们使用;
2.相对于使用Shiro 通过Filter 过滤器实现安全校验维护的Session 信息更容易理解和轻量级,提供了多端同样的访问方式。