SpringBoot-JWT+Security权限认证框架

SpringBoot-JWT+Security权限认证框架

JWT

jwt说白了就是一个字符串生成器+检查器,只不过加密了。

官网:https://jwt.io/introduction

token是一个加密的用户身份钥匙字符串,用户登录时获取它,用户请求时拿着它进行访问。
在这里插入图片描述

token在登录后生成,并返回给客户端,客户端将一直持有它。当客户端进行请求时将token携带,过滤器拦截登录未放行的请求,检查他们是否携带合法token,合法则通过,不合法则拦截。

验证token时jwt可通过token获取里面的信息,并和进行检查,检查token合法即允许通过。(token字符串是加密的串,只要它是合法的就直接允许,因此不用再比对用户密码)

token本身是一个通过base64URL编码加密的字符串:

格式如下:

aaaaaaaaa.bbbbbbbbbbbb.cccccccccccc

令牌由3个部分组成,每个部分都被base64URL加密:

  • Header:头,token的类型、及使用的算法
  • Payload:有效载荷,你添加的信息
  • Signature:签名

密码等信息请不要放进来,容易被解密。

jwt中token在加密前其实就是json文本。

1.创建token

一个token中一般存放用户信息(用户名、权限)、签发时间、过期时间、私钥即可,在创建时指定算法。


    private long key="jjlahjdahglsnaafafasfafwlalahnf";//私钥(尽量长)
    private long times=100000;						   //有效时长
    /**
     * 创建token
     * @param claims 用户信息map
     * @return token字符串
     */
    public String createToken(Map<String, Object> claims) {
        return "Bearer "+Jwts.builder() //Bearer token
                .claim("auth", claims)//claims:存放用户信息(key:auth)
                .setId(UUID.randomUUID().toString())//令牌随机ID
                .setIssuedAt(new Date()) //令牌签发时间
                .setExpiration(new Date((new Date()).getTime() +times))//令牌过期时间
                .compressWith(CompressionCodecs.DEFLATE)
                .signWith(key, SignatureAlgorithm.HS512)     //加密算法
                .compact();
    }

2.其他操作

由于操作根据你的业务需求来,所以只列举几个功能

//获取存储信息部分
Claims claims = Jwts.parser().setSigningKey(私钥key).parseClaimsJws(token).getBody();
 
//验证token中私钥,抛异常则错误
Jwts.parser().setSigningKey(私钥key).parseClaimsJws(token);

//获取权限列表
Collection<? extends GrantedAuthority> authorities = Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());

//获取用户账号信息
Map<String,Object> map = (Map<String, Object>) claims.get(AUTHORITIES_KEY);

//获取过期时间
Date expiration = claims.getExpiration();    

3.过滤器认证示例

请求时获取完token,你想验证哪些方面就判断哪些方面即可,下面的仅供参考。

/**
 * Description 实现token验证的过滤器
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        
        String token = null;
        //获取请求时携带的token全串,Authorization为请求时token的key值
        String bearerToken = request.getHeader("Authorization");

        //请求全token为字符串 且 前缀正确
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
            //获取jwt令牌串(不带附加串token)
            token = bearerToken.substring("Bearer ".length());
        }


		//下面的jwtTokenUtils是自己写的工具类,参考1、2节创建


        //token为字符串 且 私钥正确
        if (StringUtils.hasText(token) && jwtTokenUtils.validateToken(token)) {

            Authentication authentication = jwtTokenUtils.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            log.debug("set Authentication to security context for '{}', uri: {}", authentication.getName(), requestRri);
        } else {
            log.debug("no valid JWT token found, uri: {}", requestRri);
        }

        /*
         * 通知 Web 容器把请求交给 Filter 链中的下一个 Filter 去处理,
         * 如果当前调用此方法的 Filter 对象是Filter 链中的最后一个 Filter,
         * 那么将把请求交给目标 Servlet 程序去处理。
         */
        filterChain.doFilter(request, response);

    }
}

4.springboot中的依赖

可能是版本原因,私钥得设置超长,否则会报错

        <!-- jwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.10.6</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.10.6</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.10.6</version>
        </dependency>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值