一、认证分析
SpringSecurity主要是通过过滤器来实现功能的!要找到SpringSecurity实现认证和校验身份的过滤器!
1.集中式认证流程
用户认证
:
使用 UsernamePasswordAuthenticationFilter
过滤器中 attemptAuthentication
方法实现认证功能,该过滤器父类中 successfulAuthentication
方法实现认证成功后的操作。认证失败是在 unsuccessfulAuthentication
身份校验
:
使用 BasicAuthenticationFilter
过滤器中 doFilterInternal
方法验证是否登录,以决定能否进入后续过滤器。
2.分布式认证流程
用户认证
:
由于分布式项目,多数是前后端分离的架构设计,要满足可以接受异步post的认证请求参数,需要修改UsernamePasswordAuthenticationFilter过滤器中attemptAuthentication方法,让其能够接收请求体。
另外,默认successfulAuthentication方法在认证通过后,是把用户信息直接放入session就完事了,现在我们需要修改这个方法,在认证通过后生成token并返回给用户。
身份校验
:
原来BasicAuthenticationFilter过滤器中doFilterInternal方法校验用户是否登录,就是看session中是否有用户信息,要修改为验证用户携带的token是否合法,并解析出用户信息,交给SpringSecurity,以便于后续的授权功能可以正常使用。
二、具体实现
1.创建项目
创建一个SpringBoot项目.引入必要的依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.bobo</groupId>
<artifactId>security-jwt-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
2.JWT工具类
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.security.SignatureException;
import java.util.Calendar;
import java.util.Map;
public class JWTUtils {
// 秘钥
private static final String SING = "123qwaszx";
/**
* 生成Token header.payload.sing 组成
* @return
*/
public static String getToken(Map<String,String> map){
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE,7); // 默认过期时间 7天
JWTCreator.Builder builder = JWT.create();
// payload