Java安全验证之jwt(json web token)

来源:互联网 发布:淘宝营销案例 编辑:程序博客网 时间:2024/06/05 05:48

http://blog.csdn.net/u012017645/article/details/53585872


jwt token安全验证流程:用户发起登录请求,服务端创建一个加密后的jwt信息,作为token返回值,在后续请求中jwt信息作为请求头,服务端正确解密后可获取到存储的用户信息,表示验证通过;解密失败说明token无效或者已过期。


依赖:

<!-- 使用JWT在用户和服务器之间传递安全可靠的信息 --><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.6.0</version></dependency>

jwt加解密的工具类:

package cn.lsh.util;import java.security.Key;import java.util.Date;import javax.crypto.spec.SecretKeySpec;import javax.xml.bind.DatatypeConverter;import io.jsonwebtoken.Claims;import io.jsonwebtoken.JwtBuilder;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import org.apache.commons.lang.exception.ExceptionUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import cn.lsh.entity.User;import cn.lsh.vo.security.Audience;import cn.lsh.vo.security.LoginParamter;public class JwtUtils {private static final Logger LOGGER=LoggerFactory.getLogger(JwtUtils.class);private JwtUtils(){}/* * 验证jwt是否合法,即解密 */public static Claims parseJWT(String jsonWebToken,String base64Security){try {return Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(base64Security)).parseClaimsJws(jsonWebToken).getBody();} catch (Exception e) {// TODO: handle exceptionLOGGER.error("exception message is: {}", ExceptionUtils.getStackTrace(e));return null;}}/* * 创建jwt,即加密 */public static String createJWT(LoginParamter loginParamter,User user,Audience audience){long ttlmillis=audience.getExpiresSecond()*1000;String base64Security=audience.getBase64Secret();Date now=new Date(System.currentTimeMillis());        //生成签名密钥byte[] apiKeySecretBytes=DatatypeConverter.parseBase64Binary(base64Security);Key signingKey=new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName());//添加构成JWT的参数JwtBuilder builder=Jwts.builder().setHeaderParam("typ", "JWT")//typ表示token的类型.claim("role", user.getRole())// 自定义属性.claim("unique_name", loginParamter.getUserName()).claim("userid", user.getName()).setIssuer(audience.getName())// 签发者.setAudience(audience.getClientId())//接受者.signWith(SignatureAlgorithm.HS256, signingKey);// 签名算法以及密匙        //添加Token过期时间if(ttlmillis>=0){Date exp=new Date(System.currentTimeMillis()+ttlmillis);builder.setExpiration(exp)// 过期时间.setNotBefore(now);// 失效时间}//生成JWTreturn builder.compact();}public static void main(String[] args) {Claims c=parseJWT("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoi566h55CG5ZGYIiwidW5pcXVlX25hbWUiOiJsaXVzaGlodWEiLCJ1c2VyaWQiOiJsaXVzaGlodWEiLCJpc3MiOiJsaXVzaGlodWEiLCJhdWQiOiIwOThmNmJjZDQ2MjFkMzczY2FkZTRlODMyNjI3YjRmNiIsImV4cCI6MTUwMjM1OTQ1NSwibmJmIjoxNTAyMzUyMjU0fQ.OeDN4deNUlDiUmwROjxw5_xrurJt46b1RZ0K5yNKH88", "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=");System.out.println(c);}}

audience包含token的一些信息:

package cn.lsh.vo.security;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import lombok.Data;@Data//绑定属性的配置信息到该bean中,配置信息前缀为audience@ConfigurationProperties(prefix="audience")@Component@ApiModel(value="JWT")public class Audience {@ApiModelProperty(value="传入的客户端id,相当于微信的openID",required=true)private String clientId;@ApiModelProperty(value="64位公钥",required=true)private String base64Secret;@ApiModelProperty(value="令牌发行者姓名",required=true)private String name;@ApiModelProperty(value="令牌有效时间,单位为秒",required=true)private int expiresSecond;}

一、在用户登录是生成token,返回给客户端

String accessToken=JwtUtils.createJWT(loginParamter, user, audience);

二、在用户下次请求是验证token

private boolean isValidJwt(HttpServletRequest request){LOGGER.info("{} request to {}",request.getMethod(),request.getRequestURL());String authorization=request.getHeader("Authorization");LOGGER.info("authorization is: {}",authorization);//access_token的头信息,定义为bearerString headString=authorization.substring(0, 6).toLowerCase();//compareTo逐个比较两个字符串中相对字符的ascll值,所有字符都相同返回0,发现小于时返回正整数,大于时返回负整数,即ascll值的差值。if(headString.compareTo(Constants.BEARER)==0){authorization=authorization.substring(6, authorization.length());if(JwtUtils.parseJWT(authorization, audience.getBase64Secret())!=null){return true;}}return false;}





原创粉丝点击