美文网首页javaWeb学习
微服务鉴权代码实现(Spring Cloud)

微服务鉴权代码实现(Spring Cloud)

作者: 月哥说了算 | 来源:发表于2019-08-16 21:53 被阅读18次
1557906391792.png
  1. 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务进行登录
  2. 用户登录成功,后台管理微服务签发JWT TOKEN信息返回给用户
  3. 用户再次进入网关开始访问,网关过滤器接收用户携带的TOKEN
  4. 网关过滤器解析TOKEN ,判断是否有权限,如果有,则放行,如果没有则返回未认证错误。

JWT签发工具类

package com.changgou.system.util;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
/**
 * JWT工具类
 */
public class JwtUtil {

    //设置秘钥明文
    public static final String JWT_KEY = "gzy";

    /**
     * 创建token
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject, Long ttlMillis) {

        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("admin")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成加密后的秘钥 secretKey
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
}

JWT校验工具类

package com.changgou.gateway.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * jwt校验工具类
 */
public class JwtUtil {

    //设置秘钥明文
    public static final String JWT_KEY = "gzy";

    /**
     * 生成加密后的秘钥 secretKey
     *
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 解析
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }
}
本次鉴权功能有两个微服务实现,网关微服务,用户微服务。

用户微服务:

controller签发令牌:

/**
 * 登录
 * @param admin
 * @return
 */
@PostMapping("/admin/login")
public Result login(@RequestBody Admin admin){
    boolean login = adminService.login(admin);
    if(login){
        //创建token
        String token = JwtUtil.createJWT( UUID.randomUUID().toString(), admin.getLoginName(), 60 * 60 * 1000L );
        Map info=new HashMap(  );
        info.put( "username", admin.getLoginName());
        info.put( "token",token );
        return new Result(true,StatusCode.OK,"登录成功",info);
    }else{
        return new Result(false,StatusCode.LOGINERROR,"用户名或密码错误");
    }
}

网关微服务校验令牌(全局拦截器实现)

网关微服务需要的依赖:

<!--鉴权-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

拦截器:

package com.changgou.filter;

import com.changgou.utils.JwtUtil;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author :gzy
 * @date :Created in 2019/8/16
 * @description :
 * @version: 1.0
 */
@Component
public class SystemFilter implements GlobalFilter,Ordered {
    private final String TOKRN="token";
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String path = request.getURI().getPath();
        System.out.println("拦截请求地址"+path);
        //如果是登录请求不校验不拦截
        if(!path.equals("/admin/login")){
            String token = request.getHeaders().getFirst(TOKRN);
            try {
                JwtUtil.parseJWT(token);
                return chain.filter(exchange);
            } catch (Exception e) {
                e.printStackTrace();
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
//这里注意拦截顺序,一定要在去除前缀之后拦截。
        return 2;
    }
}

相关文章

网友评论

    本文标题:微服务鉴权代码实现(Spring Cloud)

    本文链接:https://www.haomeiwen.com/subject/inrcsctx.html