Commit 264889f5 by stylefeng

完善签名验校验机制

parent 9824999c
package com.stylefeng.guns.rest.common;
/**
* 测试用的
*
* @author fengshuonan
* @date 2017-08-25 16:47
*/
public class SimpleObject {
private String user;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
......@@ -30,6 +30,6 @@ public class GlobalExceptionHandler extends BaseControllerExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorTip jwtException(JwtException e) {
return new ErrorTip(BizExceptionEnum.AUTH_ERROR.getCode(), BizExceptionEnum.AUTH_ERROR.getMessage());
return new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage());
}
}
......@@ -8,10 +8,10 @@ package com.stylefeng.guns.rest.common.exception;
*/
public enum BizExceptionEnum {
AUTH_REQUEST_ERROR(700, "auth请求验证失败"),
TOKEN_EXPIRED(700, "token 过期"),
AUTH_ERROR(700, "签名错误,请求失败"),
SERVER_ERROR(802, "服务器错误");
AUTH_REQUEST_ERROR(400,"账号密码错误"),
TOKEN_ERROR(700, "token验证失败"),
SIGN_ERROR(700, "签名验证失败"),
TOKEN_EXPIRED(700, "token过期");
BizExceptionEnum(int code, String message) {
this.friendlyCode = code;
......
package com.stylefeng.guns.rest.config;
import com.stylefeng.guns.core.config.DefaultFastjsonConfig;
import com.stylefeng.guns.rest.modular.auth.converter.WithSignMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 签名校验messageConverter
*
* @author fengshuonan
* @date 2017-08-25 16:04
*/
@Configuration
public class MessageConverConfig {
@Bean
public WithSignMessageConverter withSignMessageConverter() {
WithSignMessageConverter withSignMessageConverter = new WithSignMessageConverter();
DefaultFastjsonConfig defaultFastjsonConfig = new DefaultFastjsonConfig();
withSignMessageConverter.setFastJsonConfig(defaultFastjsonConfig.fastjsonConfig());
withSignMessageConverter.setSupportedMediaTypes(defaultFastjsonConfig.getSupportedMediaType());
return withSignMessageConverter;
}
}
......@@ -23,6 +23,8 @@ public class JwtProperties {
private String authPath = "auth";
private String md5Key = "randomKey";
public static String getJwtPrefix() {
return JWT_PREFIX;
}
......@@ -58,4 +60,12 @@ public class JwtProperties {
public void setAuthPath(String authPath) {
this.authPath = authPath;
}
public String getMd5Key() {
return md5Key;
}
public void setMd5Key(String md5Key) {
this.md5Key = md5Key;
}
}
package com.stylefeng.guns.rest.modular.auth.converter;
/**
* 基础的传输bean
*
* @author fengshuonan
* @date 2017-08-25 15:52
*/
public class BaseTransferEntity {
private Object object;
private String sign;
public Object getObject() {
return object;
}
public String getSign() {
return sign;
}
public void setObject(Object object) {
this.object = object;
}
public void setSign(String sign) {
this.sign = sign;
}
}
package com.stylefeng.guns.rest.modular.auth.converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.MD5Util;
import com.stylefeng.guns.rest.common.exception.BizExceptionEnum;
import com.stylefeng.guns.rest.common.exception.BussinessException;
import com.stylefeng.guns.rest.config.properties.JwtProperties;
import com.stylefeng.guns.rest.modular.auth.util.JwtTokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
/**
* 带签名的http信息转化器
*
* @author fengshuonan
* @date 2017-08-25 15:42
*/
public class WithSignMessageConverter extends FastJsonHttpMessageConverter4 {
@Autowired
JwtProperties jwtProperties;
@Autowired
JwtTokenUtil jwtTokenUtil;
@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
InputStream in = inputMessage.getBody();
Object o = JSON.parseObject(in, super.getFastJsonConfig().getCharset(), BaseTransferEntity.class, super.getFastJsonConfig().getFeatures());
//先转化成原始的对象
BaseTransferEntity baseTransferEntity = (BaseTransferEntity) o;
//校验签名
String token = HttpKit.getRequest().getHeader(jwtProperties.getHeader()).substring(7);
String md5KeyFromToken = jwtTokenUtil.getMd5KeyFromToken(token);
String json = JSON.toJSONString(baseTransferEntity.getObject());
String encrypt = MD5Util.encrypt(json + md5KeyFromToken);
if (encrypt.equals(baseTransferEntity.getSign())) {
System.out.println("签名校验成功");
} else {
System.out.println("签名校验失败");
throw new BussinessException(BizExceptionEnum.SIGN_ERROR);
}
//校验签名后再转化成应该的对象
return JSON.parseObject(json, type);
}
}
......@@ -53,12 +53,12 @@ public class AuthFilter extends OncePerRequestFilter {
}
} catch (JwtException e) {
//有异常就是token解析失败
RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.AUTH_ERROR.getCode(), BizExceptionEnum.AUTH_ERROR.getMessage()));
RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
return;
}
} else {
//header没有带Bearer字段
RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.AUTH_ERROR.getCode(), BizExceptionEnum.AUTH_ERROR.getMessage()));
RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
return;
}
chain.doFilter(request, response);
......
......@@ -71,6 +71,13 @@ public class JwtTokenUtil {
}
/**
* 获取md5 key从token中
*/
public String getMd5KeyFromToken(String token){
return getPrivateClaimFromToken(token,jwtProperties.getMd5Key());
}
/**
* 获取jwt的payload部分
*/
public Claims getClaimFromToken(String token) {
......@@ -103,7 +110,7 @@ public class JwtTokenUtil {
*/
public String generateToken(String userName, String randomKey) {
Map<String, Object> claims = new HashMap<>();
claims.put("randomKey", randomKey);
claims.put(jwtProperties.getMd5Key(), randomKey);
return doGenerateToken(claims, userName, randomKey);
}
......
package com.stylefeng.guns.rest.modular.example;
import com.stylefeng.guns.rest.common.SimpleObject;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
/**
......@@ -15,7 +17,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class ExampleController {
@RequestMapping("")
public ResponseEntity hello() {
public ResponseEntity hello(@RequestBody SimpleObject simpleObject) {
System.out.println(simpleObject.getUser());
return ResponseEntity.ok("请求成功!");
}
}
jwt:
header: Authorization #http请求头部需要带的标识
header: Authorization #http请求头所需要的字段
secret: mySecret #jwt秘钥
expiration: 604800 #7天 单位:秒
auth-path: auth #认证请求的路径
md5-key: randomKey #md5加密混淆key
mybatis-plus:
mapper-locations: classpath*:com/stylefeng/guns/rest/**/mapping/*.xml
......
package com.stylefeng.guns.fastjson;
import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.core.util.MD5Util;
import com.stylefeng.guns.rest.common.SimpleObject;
import com.stylefeng.guns.rest.modular.auth.converter.BaseTransferEntity;
/**
* json测试
*
* @author fengshuonan
* @date 2017-08-25 16:11
*/
public class JsonTest {
public static void main(String[] args) {
String auth = "eyJhbGciOiJIUzUxMiJ9.eyJyYW5kb21LZXkiOiJmcnpubW0iLCJzdWIiOiJhZG1pbiIsImV4cCI6MTUwNDI1MzU4NSwiaWF0IjoxNTAzNjQ4Nzg1fQ.smQQlKnRgfHnfSkID6FoYpXBAMPw-NfFq4zaqc2E0Ve7V2nb0U5iIJvVMKY75lYbi1gYtDiTibqt0B39noNCHg";
String randomKey = "nv0lwt";
BaseTransferEntity baseTransferEntity = new BaseTransferEntity();
SimpleObject simpleObject = new SimpleObject();
simpleObject.setUser("fsn");
baseTransferEntity.setObject(simpleObject);
String json = JSON.toJSONString(simpleObject);
//md5签名
String encrypt = MD5Util.encrypt(json + randomKey);
baseTransferEntity.setSign(encrypt);
System.out.println(JSON.toJSONString(baseTransferEntity));
}
}
......@@ -14,7 +14,7 @@ public class DecryptTest {
String key = "mySecret";
String compactJws = "eyJhbGciOiJIUzUxMiJ9.eyJyYW5kb21LZXkiOiJjdXVuYXgiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTUwNDIzNjk1MywiaWF0IjoxNTAzNjMyMTUzfQ.8Feb8wU67zVOGuxWEllH8I_q5VKVsIHAdeJKTRLkmrhvfPzd0Xzx5C_DRvctTpzXjEw5v3czNTJyzai1Q1LpJg";
String compactJws = "eyJhbGciOiJIUzUxMiJ9.eyJyYW5kb21LZXkiOiJudjBsd3QiLCJzdWIiOiJhZG1pbiIsImV4cCI6MTUwNDI0NzA1NSwiaWF0IjoxNTAzNjQyMjU1fQ.wHzVxTvi0bmfq8YmI65tVqYfeXp5EJPzm5C_DtQOl5Fyc1HKuDJyaW-BPpjgMtjsk-mdeEBZSadoDK3LjHsy8A";
System.out.println("body = " + Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getBody());
System.out.println("header = " + Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws).getHeader());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment