Spring Boot+Spring Security+Jwt
1、项目背景
-
开发Web应用,对页面的安全控制通常是必须的。比如:对于没有访问权限的用户需要转到登录表单页面。要实现访问控制的方法多种多样,可以通过Aop、拦截器实现,也可以通过框架实现,例如:Apache Shiro、Spring Security。
-
很多成熟的大公司都会有专门针对用户管理方面有一套完整的SSO(单点登录),ACL(权限访问控制),UC(用户中心)系统。 但是在我们开发中小型系统的时候,往往还是优先选择轻量级可用的业内通用的框架解决方案。
-
Spring Security 就是一个Spring生态中关于安全方面的框架。它能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案。
-
Spring Security,是一个基于Spring AOP和Servlet过滤器的安全框架。它提供全面的安全性解决方案,同时在Web请求级和方法调用级处理身份确认和授权。在Spring Framework基础上,Spring Security充分利用了依赖注入(DI,Dependency Injection)和面向切面技术。
-
Spring Security提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(Inversion of Control, 控制反转),DI和AOP(Aspect Oriented Progamming ,面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作,为基于J2EE企业应用软件提供了全面安全服务[0]。Spring Security的前身是 Acegi Security 。
2、基本原理
UsernamePasswordAuthenticationFilter
用户表单登陆过滤器
FilterSecurityInterceptor
中的super.beforeInvocation(fi)
即最终的拦截。之后将会去我们写的服务中调用API接口信息。
ExceptionTranslationFilter
用来处理异常,调用FilterSecurityInterceptor.
2.1、基本步骤
-
1、自定义用户认证逻辑
-
处理用户信息获取逻辑
-
如果通过username找不到,那么就会抛出
UsernameNotFoundException
。找到了就会将用户信息userDetails
进行处理和校验,通过之后放入 session中。 -
User(user.getUsername(), user.getPassword(), emptyList())
,其中emptyList(),主要作用就是授权,返回当前用户拥有的一些权限信息等等。 -
2、处理用户校验逻辑
- 1、
boolean isAccountNonExpired();
用户账户是否过期 - 2、
boolean isAccountNonLocked();
用户账户是否被锁定 - 3、
boolean isCredentialsNonExpired();
密码是否过期 - 4、
boolean isEnabled();
用户是否被删除,一般都是假删除
-
-
3、处理密码加密解密
PasswordEncoder
主要作用就是密码的加解密,这个每次登陆返回的加密后的密码都是不一样的。
- 4、通过token 认证用户
-
一、创建一个类JWTLoginFilter,核心功能是在验证用户名密码正确后,生成一个token,并将token返回给客户端:
-
该类继承自UsernamePasswordAuthenticationFilter,重写了其中的2个方法:
-
attemptAuthentication :接收并解析用户凭证。
-
successfulAuthentication :用户成功登录后,这个方法会被调用,我们在这个方法里生成token。
-
-
二:授权验证
-
用户一旦登录成功后,会拿到token,后续的请求都会带着这个token,服务端会验证token的合法性。
-
创建JwtAuthenticationFilter类,我们在这个类中实现token的校验功能。
-
该类继承自BasicAuthenticationFilter,在doFilterInternal方法中,从http头的Authorization 项读取token数据,然后用Jwts包提供的方法校验token的合法性。 如果校验通过,就认为这是一个取得授权的合法请求。
-
-
三:SpringSecurity配置
-
通过SpringSecurity的配置,将上面的方法组合在一起。
-
这是标准的SpringSecurity配置内容,就不在详细说明。注意其中的
.addFilter(new JWTLoginFilter(authenticationManager())) .addFilter(new JwtAuthenticationFilter(authenticationManager()))
- 这两行,将我们定义的JWT方法加入SpringSecurity的处理流程中。
-
下边先截图显示效果
-
1、因为这个url没有授权,所以返回403。
-
2、注册一个新用户
-
3、登陆
-
4、携带token, 请求用户列表
项目地址: springboot-springsecurity-jwt
微信扫码关注java架构,获取Java面试题和架构师相关题目和视频。