**
使用security和jwt进行安全登录
**
总结
1.for循环的时候可能会报空指针异常,在获取遍历项的时候尽量使用if判断
登录流程
一、首先security进行用户验证和授权
jwt负责颁发令牌与校验,判断用户登录状态,如果有令牌则代表已经登录
二、登录
1.首先从数据库获取用户名和密码,判断用户名和密码是否正确。再将前端传回的用户名的角色和权限提取出来赋值给数据库查出来的用户对象,将密码置为空串(密码不能存在jwt的头部和载荷),接着生成令牌(令牌包含用户对象,私钥,有效时间),这个令牌交给客户端会保存在localstoryge或者sessionstoryge或者cookie中。
此时访问登录页面会401,原因是登录页面被拦截,没有登录,接着就配置security配置类。
2.过滤链最后一个过滤器检验上下文是否有用户信息
配置security配置类,针对FilterSecurityIntercepter(最后一个过滤器),放行静态资源(包含swagger的静态资源,需要放行)和系统资源(登录请求路径),此时访问登录页面403,需要关闭csrf跨站请求伪造.
3.访问登陆页面可以获取令牌,但是访问其他页面403,因为此时security没有解析令牌,上下文中没有基本信息和角色权限。下一步进行解析令牌
三、认证
自定义Basic Authentication Filter过滤器,拦截所有请求,只要带令牌了就解析令牌,将令牌中的信息解析到上下文中,没有就拒绝访问。
1)放行登录请求(登录请求不用携带令牌)
2)从请求头中获取令牌
3)解析令牌:获取用户的角色和权限信息,角色以ROLE_开头。将用户角色和权限放入context中。
需要将此实现的过滤器放入IOC容器,但是会报错,因此只能在security的配置类中配置该配置类。
四、授权
粗粒度(角色)和细粒度(权限)授权
粗粒度:(角色)@PreAuthorize(“hasAnyRole(‘ROLE_ADMIN’)”)
细粒度:(权限)@PreAuthorize(“hasAnyAuthority(‘copy’)”)
授权注解需要扫描,在security配置类开启:
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)//开启授权的注解
五、自定义异常处理
1.实现AccessDeniedHandler接口
2.在security的配置类自定义accessdenied异常处理
六、Swagger处理
swagger需要携带令牌才能访问接口