diff --git a/ace-admin/src/main/java/com/github/wxiaoqi/security/admin/rpc/LogService.java b/ace-admin/src/main/java/com/github/wxiaoqi/security/admin/rpc/LogService.java index d8bffef7a5878f164686f6dec43feb2ba104a782..e0180ed56999cc25e86ad2b29138f4f5e25c413c 100644 --- a/ace-admin/src/main/java/com/github/wxiaoqi/security/admin/rpc/LogService.java +++ b/ace-admin/src/main/java/com/github/wxiaoqi/security/admin/rpc/LogService.java @@ -1,6 +1,5 @@ package com.github.wxiaoqi.security.admin.rpc; -import com.alibaba.fastjson.JSONObject; import com.github.wxiaoqi.security.admin.biz.GateLogBiz; import com.github.wxiaoqi.security.admin.entity.GateLog; import com.github.wxiaoqi.security.api.vo.log.LogInfo; @@ -14,7 +13,7 @@ import org.springframework.web.bind.annotation.ResponseBody; /** * ${DESCRIPTION} - * + * 保存日志 * @author wanghaobin * @create 2017-07-01 14:39 */ diff --git a/ace-common/pom.xml b/ace-common/pom.xml index 8958da1ac2cf15da3f5e448aac1bcf9c728ef328..8ba693c7f8b586e71d9cbbe8b967b5da4997ad85 100644 --- a/ace-common/pom.xml +++ b/ace-common/pom.xml @@ -53,7 +53,16 @@ commons-io 1.3.2 - + + joda-time + joda-time + 2.9.9 + + + io.jsonwebtoken + jjwt + 0.7.0 + diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/constant/CommonConstants.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/constant/CommonConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..6e87eb6ae7e37e70e41d9b681813737370c34831 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/constant/CommonConstants.java @@ -0,0 +1,19 @@ +package com.github.wxiaoqi.security.common.constant; + +/** + * Created by ace on 2017/9/8. + */ +public class CommonConstants { + public static final Integer EX_TOKEN_ERROR_CODE = 40101; + public static final Integer EX_USER_INVALID_CODE = 40102; + public static final Integer EX_CLIENT_INVALID_CODE = 40131; + public static final Integer EX_CLIENT_FORBIDDEN_CODE = 40331; + public static final Integer EX_OTHER_CODE = 500; + public static final String CONTEXT_KEY_USER_ID = "currentUserId"; + public static final String CONTEXT_KEY_USERNAME = "currentUserName"; + public static final String CONTEXT_KEY_USER_NAME = "currentUser"; + public static final String JWT_KEY_USER_ID = "userId"; + public static final String JWT_KEY_NAME = "name"; + + +} diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/context/BaseContextHandler.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/context/BaseContextHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..0d90d9df219d34e55b6265f7ab536c0f6d8dc122 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/context/BaseContextHandler.java @@ -0,0 +1,65 @@ +package com.github.wxiaoqi.security.common.context; + + +import com.github.wxiaoqi.security.common.constant.CommonConstants; +import com.github.wxiaoqi.security.common.util.StringHelper; + +import java.util.HashMap; +import java.util.Map; + + + +/** + * Created by ace on 2017/9/8. + */ +public class BaseContextHandler { + public static ThreadLocal> threadLocal = new ThreadLocal>(); + + public static void set(String key, Object value) { + Map map = threadLocal.get(); + if (map == null) { + map = new HashMap(); + threadLocal.set(map); + } + map.put(key, value); + } + + public static Object get(String key){ + Map map = threadLocal.get(); + if (map == null) { + map = new HashMap(); + threadLocal.set(map); + } + return map.get(key); + } + + public static String getUserID(){ + Object value = get(CommonConstants.CONTEXT_KEY_USER_ID); + return StringHelper.getObjectValue(value); + } + + public static String getUsername(){ + Object value = get(CommonConstants.CONTEXT_KEY_USERNAME); + return StringHelper.getObjectValue(value); + } + + public static String getName(){ + Object value = get(CommonConstants.CONTEXT_KEY_USER_NAME); + return StringHelper.getObjectValue(value); + } + + public static void setUserID(String userID){ + set(CommonConstants.CONTEXT_KEY_USER_ID,userID); + } + + public static void setUsername(String username){ + set(CommonConstants.CONTEXT_KEY_USERNAME,username); + } + + public static void setName(String name){set(CommonConstants.CONTEXT_KEY_USER_NAME,name);} + + public static void remove(){ + threadLocal.remove(); + } + +} diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/KeyHelper.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/KeyHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..ab34991a30c7747863ce57fa0a7d01993f1b36c7 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/KeyHelper.java @@ -0,0 +1,75 @@ +package com.github.wxiaoqi.security.common.util; + +import java.io.*; +import java.security.*; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * Created by ace on 2017/9/10. + */ +public class KeyHelper { + /** + * 获取公钥 + * @param filename + * @return + * @throws Exception + */ + public static PublicKey getPublicKey(String filename) throws Exception { + File f = new File(filename); + FileInputStream fis = new FileInputStream(f); + DataInputStream dis = new DataInputStream(fis); + byte[] keyBytes = new byte[(int) f.length()]; + dis.readFully(keyBytes); + dis.close(); + X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePublic(spec); + } + + /** + * 获取密钥 + * @param filename + * @return + * @throws Exception + */ + public static PrivateKey getPrivateKey(String filename) throws Exception { + File f = new File(filename); + FileInputStream fis = new FileInputStream(f); + DataInputStream dis = new DataInputStream(fis); + byte[] keyBytes = new byte[(int) f.length()]; + dis.readFully(keyBytes); + dis.close(); + PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory kf = KeyFactory.getInstance("RSA"); + return kf.generatePrivate(spec); + } + + /** + * 生存rsa公钥和密钥 + * @param publicKeyFilename + * @param privateKeyFilename + * @param password + * @throws IOException + * @throws NoSuchAlgorithmException + */ + public static void generateKey(String publicKeyFilename,String privateKeyFilename,String password) throws IOException, NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + SecureRandom secureRandom = new SecureRandom(password.getBytes()); + keyPairGenerator.initialize(1024, secureRandom); + KeyPair keyPair = keyPairGenerator.genKeyPair(); + byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); + FileOutputStream fos = new FileOutputStream(publicKeyFilename); + fos.write(publicKeyBytes); + fos.close(); + byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); + fos = new FileOutputStream(privateKeyFilename); + fos.write(privateKeyBytes); + fos.close(); + } + + public static void main(String[] args) throws IOException, NoSuchAlgorithmException { + generateKey("/Users/ace/git/ag-parent/ag-auth/src/main/resources/client/pub.key","/Users/ace/git/ag-parent/ag-auth/src/main/resources/client/pri.key","1*&623!f"); + } +} + diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/StringHelper.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/StringHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..0343167640342040f8164f526ba5851d604bef36 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/StringHelper.java @@ -0,0 +1,10 @@ +package com.github.wxiaoqi.security.common.util; + +/** + * Created by ace on 2017/9/10. + */ +public class StringHelper { + public static String getObjectValue(Object obj){ + return obj==null?"":obj.toString(); + } +} diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/IJWTInfo.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/IJWTInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..589415a1fb98fd4938e75359011fa287b6149adc --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/IJWTInfo.java @@ -0,0 +1,24 @@ +package com.github.wxiaoqi.security.common.util.jwt; + +/** + * Created by ace on 2017/9/10. + */ +public interface IJWTInfo { + /** + * 获取用户名 + * @return + */ + String getUniqueName(); + + /** + * 获取用户ID + * @return + */ + String getId(); + + /** + * 获取名称 + * @return + */ + String getName(); +} diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTHelper.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..fca56243c5d407ec0d504c53afb155bb9d30e4d3 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTHelper.java @@ -0,0 +1,63 @@ +package com.github.wxiaoqi.security.common.util.jwt; + + +import com.github.wxiaoqi.security.common.constant.CommonConstants; +import com.github.wxiaoqi.security.common.util.KeyHelper; +import com.github.wxiaoqi.security.common.util.StringHelper; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import org.joda.time.DateTime; + +/** + * Created by ace on 2017/9/10. + */ +public class JWTHelper { + /** + * 密钥加密token + * + * @param jwtInfo + * @param priKeyPath + * @param expire + * @return + * @throws Exception + */ + public static String generateToken(IJWTInfo jwtInfo, String priKeyPath, int expire) throws Exception { + String compactJws = Jwts.builder() + .setSubject(jwtInfo.getUniqueName()) + .claim(CommonConstants.JWT_KEY_USER_ID, jwtInfo.getId()) + .claim(CommonConstants.JWT_KEY_NAME, jwtInfo.getName()) + .setExpiration(DateTime.now().plusSeconds(expire).toDate()) + .signWith(SignatureAlgorithm.RS256, KeyHelper.getPrivateKey(priKeyPath)) + .compact(); + return compactJws; + } + + /** + * 公钥解析token + * + * @param token + * @return + * @throws Exception + */ + public static Jws parserToken(String token, String pubKeyPath) throws Exception { + Jws claimsJws = Jwts.parser().setSigningKey(KeyHelper.getPublicKey(pubKeyPath)).parseClaimsJws(token); + return claimsJws; + } + + /** + * 获取token中的用户信息 + * + * @param token + * @param pubKeyPath + * @return + * @throws Exception + */ + public static IJWTInfo getInfoFromToken(String token, String pubKeyPath) throws Exception { + Jws claimsJws = parserToken(token, pubKeyPath); + Claims body = claimsJws.getBody(); + return new JWTInfo(body.getSubject(), StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_USER_ID)), StringHelper.getObjectValue(body.get(CommonConstants.JWT_KEY_NAME))); + } + +} diff --git a/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTInfo.java b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..86394753b59c7b4f6b47b62053f44627a9a80699 --- /dev/null +++ b/ace-common/src/main/java/com/github/wxiaoqi/security/common/util/jwt/JWTInfo.java @@ -0,0 +1,61 @@ +package com.github.wxiaoqi.security.common.util.jwt; + +import java.io.Serializable; + +/** + * Created by ace on 2017/9/10. + */ +public class JWTInfo implements Serializable,IJWTInfo { + private String username; + private String userId; + private String name; + + public JWTInfo(String username, String userId, String name) { + this.username = username; + this.userId = userId; + this.name = name; + } + + public String getUniqueName() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JWTInfo jwtInfo = (JWTInfo) o; + + if (username != null ? !username.equals(jwtInfo.username) : jwtInfo.username != null) return false; + return userId != null ? userId.equals(jwtInfo.userId) : jwtInfo.userId == null; + + } + + @Override + public int hashCode() { + int result = username != null ? username.hashCode() : 0; + result = 31 * result + (userId != null ? userId.hashCode() : 0); + return result; + } +} diff --git a/ace-gate/src/main/java/com/github/wxiaoqi/security/gate/filter/SessionAccessFilter.java b/ace-gate/src/main/java/com/github/wxiaoqi/security/gate/filter/SessionAccessFilter.java index d54408a6693177e9c12fc027e369b7e8b284e333..a05f8d99fcb8fe46f8f99ef3d7b8755f64f132fb 100644 --- a/ace-gate/src/main/java/com/github/wxiaoqi/security/gate/filter/SessionAccessFilter.java +++ b/ace-gate/src/main/java/com/github/wxiaoqi/security/gate/filter/SessionAccessFilter.java @@ -29,7 +29,7 @@ import java.util.regex.Pattern; /** * ${DESCRIPTION} - * + * 权限过滤器。 * @author wanghaobin * @create 2017-06-23 8:25 */