首页 > 编程知识 正文

token实现单点登录,jwt单点登录用法跨域

时间:2023-05-04 08:12:00 阅读:132252 作者:4198

1、认证过程

登录:

1 )首次认证)首次登录时,用户在浏览器中输入用户名/密码,提交后登录服务器处理的操作层(登录操作);

2 )登录操作调用认证服务进行用户名密码认证,认证通过时,登录操作层调用用户信息服务获取用户信息(包括与完整用户信息相对应的权限信息)。

3 )返回用户信息后,Login Action从配置文件中获取Token签名生成的私钥信息,进行Token生成;

4 )在生成Token的过程中,可以调用第三方的JWT Lib生成签名的JWT数据

5 ) JWT数据签名完成后,设置为COOKIE对象,重定向到首页,完成登录过程;

要求认证:

基于Token的认证机制将为每个请求带来签名的Token信息。 此Token信息可能位于COOKIE中

那么,可能在HTTP的授权的脑子里;

1 )客户端(APP客户端或浏览器)请求通过GET或POST访问资源)调用页面或API )

2 )认证服务以Middleware HOOK身份监听请求,首先在cookie中查找Token信息,如果找不到,则在http授权头中查找

3 )如果找到Token信息,则基于配置文件中的签名加密私钥,调用JWT Lib对Token信息进行解密和解密;

4 )解密完成并验证签名通过后,验证Token的exp、nbf、aud等信息

5 )全部通过后,根据获取的用户角色权限信息,对请求的资源进行权限逻辑判断

6 )如果通过权限逻辑判断,则返回Response对象,否则返回HTTP 401;

2、部分代码

用户登录时:

如果用户要求:

JWTUtils.java :

package com.sxt.sso.commons; import java.util.Date; 导入javax.crypto.secret key; import javax.crypto.spec.secret key spec; import com.faster XML.ww dhb.core.jsonprocessingexception; import com.faster XML.ww dhb.databind.object mapper; import io.jsonwebtoken.Claims; import io.jsonwebtoken.expiredjwtexception; import io.jsonwebtoken.jwt builder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.signature algorithm; import io.jsonwebtoken.signature exception; /** * JWT工具* /公共类jwt utils {//服务器的密钥。 用于解除加密的密钥数据。 如果客户端生成的密钥可用。 可以不使用当前定义的常时点亮。 privatestaticfinalstringjwt _ secert=' test _ jwt _ secert '; 私有对象映射器=new对象映射器(; publicstaticfinalintjwt _ errcode _ expire=1005; //Token过期publicstaticfinalintjwt _ errcode _ fail=1006; //验证为publicstaticsecretkeygeneralkey () try )/byte [ ] encoded key=base64.decode ) jwt_secert ); //无论如何,如果最终得到一个byte[]类型的密钥,则byte [ ] encoded密钥=jwt _ secert.getbytes (utf-8 ); secret keykey=newsecretkeyspec (编码密钥,0,编码密钥. length,' AES ' ); 返回密钥; }catch(exceptione ) { e.printStackTrace ); 返回空值; 如何发布}//***jwt并创建token。 * @param id jwt的唯一id主要用作一次性token,以避免重放攻击。 * @param iss jwt发行者* @param subject jwt目标用户。 payload中记录的公共剪辑

。当前环境中就是用户的登录名。 * @param ttlMillis 有效期,单位毫秒 * @return token, token是一次性的。是为一个用户的有效登录周期准备的一个token。用户退出或超时,token失效。 * @throws Exception */ public static String createJWT(String id,String iss, String subject, long ttlMillis) { // 加密算法 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; // 当前时间。 long nowMillis = System.currentTimeMillis(); // 当前时间的日期对象。 Date now = new Date(nowMillis); SecretKey secretKey = generalKey(); // 创建JWT的构建器。 就是使用指定的信息和加密算法,生成Token的工具。 JwtBuilder builder = Jwts.builder() .setId(id) // 设置身份标志。就是一个客户端的唯一标记。 如:可以使用用户的主键,客户端的IP,服务器生成的随机数据。 .setIssuer(iss) .setSubject(subject) .setIssuedAt(now) // token生成的时间。 .signWith(signatureAlgorithm, secretKey); // 设定密匙和算法 if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis; Date expDate = new Date(expMillis); // token的失效时间。 builder.setExpiration(expDate); } return builder.compact(); // 生成token } /** * 验证JWT * @param jwtStr * @return */ public static JWTResult validateJWT(String jwtStr) { JWTResult checkResult = new JWTResult(); Claims claims = null; try { claims = parseJWT(jwtStr); checkResult.setSuccess(true); checkResult.setClaims(claims); } catch (ExpiredJwtException e) { // token超时 checkResult.setErrCode(JWT_ERRCODE_EXPIRE); checkResult.setSuccess(false); } catch (SignatureException e) { // 校验失败 checkResult.setErrCode(JWT_ERRCODE_FAIL); checkResult.setSuccess(false); } catch (Exception e) { checkResult.setErrCode(JWT_ERRCODE_FAIL); checkResult.setSuccess(false); } return checkResult; } /** * * 解析JWT字符串 * @param jwt 就是服务器为客户端生成的签名数据,就是token。 * @return * @throws Exception */ public static Claims parseJWT(String jwt) throws Exception { SecretKey secretKey = generalKey(); return Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(jwt) .getBody(); // getBody获取的就是token中记录的payload数据。就是payload中保存的所有的claims。 } /** * 生成subject信息 * @param subObj - 要转换的对象。 * @return java对象->JSON字符串出错时返回null */ public static String generalSubject(Object subObj){ try { return MAPPER.writeValueAsString(subObj); } catch (JsonProcessingException e) { e.printStackTrace(); return null; } } }

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。