Jelajahi Sumber

增加对优软云账户中心的支持

yingp 7 tahun lalu
induk
melakukan
f5b73b6497

+ 74 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/cookie/CookieHelper.java

@@ -0,0 +1,74 @@
+package com.usoftchina.saas.auth.common.cookie;
+
+import com.usoftchina.saas.auth.common.crypto.Rc4Utils;
+import com.usoftchina.saas.exception.BizException;
+import com.usoftchina.saas.exception.ExceptionCode;
+import com.usoftchina.saas.utils.JsonUtils;
+import com.usoftchina.saas.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author yingp
+ * @date 2018/11/15
+ */
+public class CookieHelper {
+
+    private static final Logger logger = LoggerFactory.getLogger(CookieHelper.class);
+
+    private static final String CUT_SYMBOL = "#";
+
+    /**
+     * 解析token
+     *
+     * @param token      token
+     * @param secretKey  私钥
+     * @return
+     * @throws BizException
+     */
+    public static CookieToken parseToken(String token, String secretKey) throws BizException {
+        try {
+            String jsonToken = Rc4Utils.decrypt(token, secretKey);
+            return JsonUtils.fromJsonString(jsonToken.split(CUT_SYMBOL)[0], CookieToken.class);
+        } catch (Exception e) {
+            logger.error(e.getMessage());
+            throw new BizException(ExceptionCode.COOKIE_ILLEGAL_ARGUMENT);
+        }
+    }
+
+    /**
+     * 获取token中的用户信息
+     *
+     * @param token
+     * @param secretKey
+     * @return
+     * @throws BizException
+     */
+    public static CookieInfo geInfoFromToken(String token, String secretKey) throws BizException {
+        CookieToken cookieToken = parseToken(token, secretKey);
+        if (!StringUtils.isEmpty(cookieToken.getData())) {
+            return JsonUtils.fromJsonString(cookieToken.getData(), CookieInfo.class);
+        }
+        return null;
+    }
+
+    /**
+     * 获取token中的用户信息
+     *
+     * @param request
+     * @param cookieName
+     * @param secretKey
+     * @return
+     * @throws BizException
+     */
+    public static CookieInfo geInfoFromRequest(HttpServletRequest request, String cookieName, String secretKey) throws BizException {
+        Cookie cookie = CookieUtils.getCookie(request, cookieName);
+        if (null != cookie) {
+            return geInfoFromToken(cookie.getValue(), secretKey);
+        }
+        return null;
+    }
+}

+ 277 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/cookie/CookieInfo.java

@@ -0,0 +1,277 @@
+package com.usoftchina.saas.auth.common.cookie;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author yingp
+ * @date 2018/11/15
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class CookieInfo implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * uu号
+     */
+    private Long userUU;
+
+    /**
+     * 会员名
+     */
+    private String vipName;
+
+    /**
+     * 手机号
+     */
+    private String mobile;
+
+    /**
+     * 手机号所属区域(continent or Hongkong)
+     */
+    private String mobileArea;
+
+    /**
+     * 手机号认证状态
+     */
+    private Short mobileValidCode;
+
+    /**
+     * 用户密码
+     */
+    private String password;
+
+    /**
+     * 用户erp密码
+     */
+    private String erpPassword;
+
+    /**
+     * 盐值
+     */
+    private String salt;
+
+    /**
+     * 用户邮箱
+     */
+    private String email;
+
+    /**
+     * 用户邮箱认证状态
+     */
+    private Short emailValidCode;
+
+    /**
+     * 身份认证状态
+     */
+    private Short identityValidCode;
+
+    /**
+     * 账户是否冻结(1、冻结)
+     */
+    private Short lock;
+
+    /**
+     * 企业uu号
+     */
+    private Long spaceUU;
+
+    /**
+     * 企业名称
+     */
+    private String spaceName;
+
+    /**
+     * 营业执照号
+     */
+    private String businessCode;
+
+    /**
+     * 企业域名
+     */
+    private String spaceDomain;
+
+    /**
+     * 应用唯一标志
+     */
+    private String appId;
+
+    /**
+     * 上次登录时间
+     */
+    private Date lastLoginTime;
+
+    public Long getUserUU() {
+        return userUU;
+    }
+
+    public void setUserUU(Long userUU) {
+        this.userUU = userUU;
+    }
+
+    public String getVipName() {
+        return vipName;
+    }
+
+    public void setVipName(String vipName) {
+        this.vipName = vipName;
+    }
+
+    public String getMobile() {
+        return mobile;
+    }
+
+    public void setMobile(String mobile) {
+        this.mobile = mobile;
+    }
+
+    public String getMobileArea() {
+        return mobileArea;
+    }
+
+    public void setMobileArea(String mobileArea) {
+        this.mobileArea = mobileArea;
+    }
+
+    public Short getMobileValidCode() {
+        return mobileValidCode;
+    }
+
+    public void setMobileValidCode(Short mobileValidCode) {
+        this.mobileValidCode = mobileValidCode;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getErpPassword() {
+        return erpPassword;
+    }
+
+    public void setErpPassword(String erpPassword) {
+        this.erpPassword = erpPassword;
+    }
+
+    public String getSalt() {
+        return salt;
+    }
+
+    public void setSalt(String salt) {
+        this.salt = salt;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public Short getEmailValidCode() {
+        return emailValidCode;
+    }
+
+    public void setEmailValidCode(Short emailValidCode) {
+        this.emailValidCode = emailValidCode;
+    }
+
+    public Short getIdentityValidCode() {
+        return identityValidCode;
+    }
+
+    public void setIdentityValidCode(Short identityValidCode) {
+        this.identityValidCode = identityValidCode;
+    }
+
+    public Short getLock() {
+        return lock;
+    }
+
+    public void setLock(Short lock) {
+        this.lock = lock;
+    }
+
+    public Long getSpaceUU() {
+        return spaceUU;
+    }
+
+    public void setSpaceUU(Long spaceUU) {
+        this.spaceUU = spaceUU;
+    }
+
+    public String getSpaceName() {
+        return spaceName;
+    }
+
+    public void setSpaceName(String spaceName) {
+        this.spaceName = spaceName;
+    }
+
+    public String getBusinessCode() {
+        return businessCode;
+    }
+
+    public void setBusinessCode(String businessCode) {
+        this.businessCode = businessCode;
+    }
+
+    public String getSpaceDomain() {
+        return spaceDomain;
+    }
+
+    public void setSpaceDomain(String spaceDomain) {
+        this.spaceDomain = spaceDomain;
+    }
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public Date getLastLoginTime() {
+        return lastLoginTime;
+    }
+
+    public void setLastLoginTime(Date lastLoginTime) {
+        this.lastLoginTime = lastLoginTime;
+    }
+
+    @Override
+    public String toString() {
+        return "CookieInfo{" +
+                "userUU=" + userUU +
+                ", vipName='" + vipName + '\'' +
+                ", mobile='" + mobile + '\'' +
+                ", mobileArea='" + mobileArea + '\'' +
+                ", mobileValidCode=" + mobileValidCode +
+                ", password='" + password + '\'' +
+                ", erpPassword='" + erpPassword + '\'' +
+                ", salt='" + salt + '\'' +
+                ", email='" + email + '\'' +
+                ", emailValidCode=" + emailValidCode +
+                ", identityValidCode=" + identityValidCode +
+                ", lock=" + lock +
+                ", spaceUU=" + spaceUU +
+                ", spaceName='" + spaceName + '\'' +
+                ", businessCode='" + businessCode + '\'' +
+                ", spaceDomain='" + spaceDomain + '\'' +
+                ", appId='" + appId + '\'' +
+                ", lastLoginTime=" + lastLoginTime +
+                '}';
+    }
+}

+ 115 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/cookie/CookieToken.java

@@ -0,0 +1,115 @@
+package com.usoftchina.saas.auth.common.cookie;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2018/11/15
+ */
+public class CookieToken implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /* 正常 */
+    public final static int FLAG_NORMAL = 0;
+
+    /* 缓存宕机 */
+    public final static int FLAG_CACHE_SHUT = 1;
+
+    /* 系统名称 */
+    private String app;
+
+    /* 登录类型 */
+    private Integer type;
+
+    /* 预留 */
+    private String data;
+
+    /* 用户 ID(长整型) */
+    private Long id;
+
+    /* 用户 ID(字符串类型,默认 fastjson 无值该参数不参与 json 序列化) */
+    private String uid;
+
+    /* 登录 IP */
+    private String ip;
+
+    /* 创建 token 当前系统时间 */
+    private long time = System.currentTimeMillis();
+
+    /**
+     * Token 状态标示
+     * <p>
+     * 默认正常执行
+     * </p>
+     */
+    private int flag = FLAG_NORMAL;
+
+    public String getApp() {
+        return app;
+    }
+
+    public void setApp(String app) {
+        this.app = app;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public int getFlag() {
+        return flag;
+    }
+
+    public void setFlag(int flag) {
+        this.flag = flag;
+    }
+
+    public long getTime() {
+        return time;
+    }
+
+    public void setTime(long time) {
+        this.time = time;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+}
+

+ 126 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/cookie/CookieUtils.java

@@ -0,0 +1,126 @@
+package com.usoftchina.saas.auth.common.cookie;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Optional;
+
+/**
+ * @author yingp
+ * @date 2018/1/25
+ */
+public class CookieUtils {
+
+    /**
+     * get cookie by name
+     *
+     * @param request
+     * @param cookieName
+     * @return
+     */
+    public static Cookie getCookie(HttpServletRequest request, String cookieName) {
+        return Optional.ofNullable(request.getCookies())
+                .map(Arrays::asList)
+                .orElse(Collections.emptyList()).stream()
+                .filter(cookie -> cookie.getName().equals(cookieName))
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * set cookie
+     *
+     * @param request
+     * @param response
+     * @param cookieName
+     * @param cookieValue
+     */
+    public static void setCookie(HttpServletRequest request, HttpServletResponse response,
+                                 String cookieName, String cookieValue) {
+        Cookie cookie = getCookie(request, cookieName);
+        if (null == cookie) {
+            cookie = new Cookie(cookieName, cookieValue);
+            cookie.setPath("/");
+            cookie.setMaxAge(-1);
+        } else if (!cookie.getValue().equals(cookieValue)) {
+            cookie.setValue(cookieValue);
+        } else {
+            return;
+        }
+        addHttpOnlyCookie(response, cookie);
+    }
+
+    /**
+     *
+     * <p>
+     * 解决 servlet 3.0 以下版本不支持 HttpOnly
+     * </p>
+     *
+     * @param response
+     *            HttpServletResponse类型的响应
+     * @param cookie
+     *            要设置httpOnly的cookie对象
+     */
+    public static void addHttpOnlyCookie(HttpServletResponse response, Cookie cookie) {
+        if (cookie == null) {
+            return;
+        }
+        /**
+         * 依次取得cookie中的名称、值、 最大生存时间、路径、域和是否为安全协议信息
+         */
+        String cookieName = cookie.getName();
+        String cookieValue = cookie.getValue();
+        int maxAge = cookie.getMaxAge();
+        String path = cookie.getPath();
+        String domain = cookie.getDomain();
+        boolean isSecure = cookie.getSecure();
+        StringBuffer sf = new StringBuffer();
+        sf.append(cookieName + "=" + cookieValue + ";");
+
+        if (maxAge >= 0) {
+            sf.append("Max-Age=" + cookie.getMaxAge() + ";");
+        }
+
+        if (domain != null) {
+            sf.append("domain=" + domain + ";");
+        }
+
+        if (path != null) {
+            sf.append("path=" + path + ";");
+        }
+
+        if (isSecure) {
+            sf.append("secure;HTTPOnly;");
+        } else {
+            sf.append("HTTPOnly;");
+        }
+
+        response.addHeader("Set-Cookie", sf.toString());
+    }
+
+    /**
+     * 清除指定Cookie
+     *
+     * @param response
+     * @param cookieName
+     *            cookie name
+     * @return boolean
+     */
+    public static void clearCookie(HttpServletRequest request, HttpServletResponse response,
+                                   String cookieName) {
+        Cookie cookie = getCookie(request, cookieName);
+        if (null != cookie) {
+            Cookie newCookie = new Cookie(cookieName, "");
+            newCookie.setMaxAge(0);
+            if (null != cookie.getDomain()) {
+                newCookie.setDomain(cookie.getDomain());
+            }
+            newCookie.setPath(cookie.getPath());
+            newCookie.setSecure(cookie.getSecure());
+            newCookie.setHttpOnly(cookie.isHttpOnly());
+            addHttpOnlyCookie(response, newCookie);
+        }
+    }
+
+}

+ 28 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/crypto/Hex.java

@@ -0,0 +1,28 @@
+package com.usoftchina.saas.auth.common.crypto;
+
+/**
+ * @author yingp
+ * @date 2018/1/31
+ */
+public final class Hex {
+
+    private static final char[] HEX = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    public static char[] encode(byte[] bytes) {
+        final int nBytes = bytes.length;
+        char[] result = new char[2*nBytes];
+
+        int j = 0;
+        for (int i=0; i < nBytes; i++) {
+            // Char for top 4 bits
+            result[j++] = HEX[(0xF0 & bytes[i]) >>> 4 ];
+            // Bottom 4
+            result[j++] = HEX[(0x0F & bytes[i])];
+        }
+
+        return result;
+    }
+
+}

+ 76 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/crypto/Rc4Utils.java

@@ -0,0 +1,76 @@
+package com.usoftchina.saas.auth.common.crypto;
+
+import com.usoftchina.saas.auth.common.crypto.base64.UrlBase64;
+import com.usoftchina.saas.auth.common.exception.AuthException;
+import org.springframework.util.DigestUtils;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * @author yingp
+ * @date 2018/1/25
+ */
+public class Rc4Utils {
+
+    final static String ALGORITHM = "RC4";
+
+    final static String defaultCharset = "UTF-8";
+
+    public static String encrypt(String value, String key) throws Exception {
+        byte[] b = UrlBase64.encode(encrypt(value.getBytes(), key));
+        return new String(b, defaultCharset);
+    }
+
+    public static String decrypt(String value, String key) throws Exception {
+        byte[] b = decrypt(UrlBase64.decode(value), key);
+        return new String(b, defaultCharset);
+    }
+
+    /**
+     * generate KEY
+     */
+    private static SecretKey toKey(String strKey) throws Exception {
+		/*
+		 * MD5 处理密钥
+		 */
+        byte[] key = DigestUtils.md5Digest(strKey.getBytes(defaultCharset));
+        return new SecretKeySpec(key, ALGORITHM);
+    }
+
+    /**
+     * 解密
+     *
+     * @param data
+     * @param key
+     * @return
+     */
+    public static byte[] decrypt(byte[] data, String key) {
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+            cipher.init(Cipher.DECRYPT_MODE, toKey(key));
+            return cipher.doFinal(data);
+        } catch (Exception e) {
+            throw new AuthException(e);
+        }
+    }
+
+    /**
+     * 加密
+     *
+     * @param data
+     * @param key
+     * @return
+     */
+    public static byte[] encrypt(byte[] data, String key) {
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+            cipher.init(Cipher.ENCRYPT_MODE, toKey(key));
+            return cipher.doFinal(data);
+        } catch (Exception e) {
+            throw new AuthException(e);
+        }
+    }
+
+}

+ 104 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/crypto/base64/UrlBase64.java

@@ -0,0 +1,104 @@
+package com.usoftchina.saas.auth.common.crypto.base64;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Convert binary data to and from UrlBase64 encoding. This is identical to
+ * Base64 encoding, except that the padding character is "." and the other
+ * non-alphanumeric characters are "-" and "_" instead of "+" and "/".
+ * <p>
+ * The purpose of UrlBase64 encoding is to provide a compact encoding of binary
+ * data that is safe for use as an URL parameter. Base64 encoding does not
+ * produce encoded values that are safe for use in URLs, since "/" can be
+ * interpreted as a path delimiter; "+" is the encoded form of a space; and "="
+ * is used to separate a name from the corresponding value in an URL parameter.
+ */
+public class UrlBase64 {
+
+	private static final UrlBase64Encoder encoder = new UrlBase64Encoder();
+
+	/**
+	 * Encode the input data producing a URL safe base 64 encoded byte array.
+	 *
+	 * @return a byte array containing the URL safe base 64 encoded data.
+	 */
+	public static byte[] encode(byte[] data) {
+		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+		try {
+			encoder.encode(data, 0, data.length, bOut);
+		} catch (Exception e) {
+			throw new IllegalStateException("exception encoding URL safe base64 data: " + e.getMessage(), e);
+		}
+
+		return bOut.toByteArray();
+	}
+
+	/**
+	 * Encode the byte data writing it to the given output stream.
+	 *
+	 * @return the number of bytes produced.
+	 */
+	public static int encode(byte[] data, OutputStream out) throws IOException {
+		return encoder.encode(data, 0, data.length, out);
+	}
+
+	/**
+	 * Decode the URL safe base 64 encoded input data - white space will be
+	 * ignored.
+	 *
+	 * @return a byte array representing the decoded data.
+	 */
+	public static byte[] decode(byte[] data) {
+		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+		try {
+			encoder.decode(data, 0, data.length, bOut);
+		} catch (Exception e) {
+			throw new IllegalStateException("exception decoding URL safe base64 string: " + e.getMessage(), e);
+		}
+
+		return bOut.toByteArray();
+	}
+
+	/**
+	 * decode the URL safe base 64 encoded byte data writing it to the given
+	 * output stream, whitespace characters will be ignored.
+	 *
+	 * @return the number of bytes produced.
+	 */
+	public static int decode(byte[] data, OutputStream out) throws IOException {
+		return encoder.decode(data, 0, data.length, out);
+	}
+
+	/**
+	 * decode the URL safe base 64 encoded String data - whitespace will be
+	 * ignored.
+	 *
+	 * @return a byte array representing the decoded data.
+	 */
+	public static byte[] decode(String data) {
+		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+		try {
+			encoder.decode(data, bOut);
+		} catch (Exception e) {
+			throw new IllegalStateException("exception decoding URL safe base64 string: " + e.getMessage(), e);
+		}
+
+		return bOut.toByteArray();
+	}
+
+	/**
+	 * Decode the URL safe base 64 encoded String data writing it to the given
+	 * output stream, whitespace characters will be ignored.
+	 *
+	 * @return the number of bytes produced.
+	 */
+	public static int decode(String data, OutputStream out) throws IOException {
+		return encoder.decode(data, out);
+	}
+
+}

+ 276 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/crypto/base64/UrlBase64Encoder.java

@@ -0,0 +1,276 @@
+package com.usoftchina.saas.auth.common.crypto.base64;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author yingp
+ * @date 2018/1/26
+ */
+public class UrlBase64Encoder {
+    protected final byte[] encodingTable = { (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
+            (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
+            (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
+            (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
+            (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
+            (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
+            (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '-', (byte) '_' };
+
+    protected byte padding = (byte) '.';
+
+    /*
+     * set up the decoding table.
+     */
+    protected final byte[] decodingTable = new byte[128];
+
+    protected void initialiseDecodingTable() {
+        for (int i = 0; i < decodingTable.length; i++) {
+            decodingTable[i] = (byte) 0xff;
+        }
+
+        for (int i = 0; i < encodingTable.length; i++) {
+            decodingTable[encodingTable[i]] = (byte) i;
+        }
+    }
+
+    public UrlBase64Encoder() {
+        initialiseDecodingTable();
+    }
+
+    /**
+     * encode the input data producing a base 64 output stream.
+     *
+     * @return the number of bytes produced.
+     */
+    public int encode(byte[] data, int off, int length, OutputStream out) throws IOException {
+        int modulus = length % 3;
+        int dataLength = (length - modulus);
+        int a1, a2, a3;
+
+        for (int i = off; i < off + dataLength; i += 3) {
+            a1 = data[i] & 0xff;
+            a2 = data[i + 1] & 0xff;
+            a3 = data[i + 2] & 0xff;
+
+            out.write(encodingTable[(a1 >>> 2) & 0x3f]);
+            out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]);
+            out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]);
+            out.write(encodingTable[a3 & 0x3f]);
+        }
+
+		/*
+		 * process the tail end.
+		 */
+        int b1, b2, b3;
+        int d1, d2;
+
+        switch (modulus) {
+            case 0: /* nothing left to do */
+                break;
+            case 1:
+                d1 = data[off + dataLength] & 0xff;
+                b1 = (d1 >>> 2) & 0x3f;
+                b2 = (d1 << 4) & 0x3f;
+
+                out.write(encodingTable[b1]);
+                out.write(encodingTable[b2]);
+                out.write(padding);
+                out.write(padding);
+                break;
+            case 2:
+                d1 = data[off + dataLength] & 0xff;
+                d2 = data[off + dataLength + 1] & 0xff;
+
+                b1 = (d1 >>> 2) & 0x3f;
+                b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
+                b3 = (d2 << 2) & 0x3f;
+
+                out.write(encodingTable[b1]);
+                out.write(encodingTable[b2]);
+                out.write(encodingTable[b3]);
+                out.write(padding);
+                break;
+        }
+
+        return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4);
+    }
+
+    private boolean ignore(char c) {
+        return (c == '\n' || c == '\r' || c == '\t' || c == ' ');
+    }
+
+    /**
+     * decode the base 64 encoded byte data writing it to the given output
+     * stream, whitespace characters will be ignored.
+     *
+     * @return the number of bytes produced.
+     */
+    public int decode(byte[] data, int off, int length, OutputStream out) throws IOException {
+        byte b1, b2, b3, b4;
+        int outLen = 0;
+
+        int end = off + length;
+
+        while (end > off) {
+            if (!ignore((char) data[end - 1])) {
+                break;
+            }
+
+            end--;
+        }
+
+        int i = off;
+        int finish = end - 4;
+
+        i = nextI(data, i, finish);
+
+        while (i < finish) {
+            b1 = decodingTable[data[i++]];
+
+            i = nextI(data, i, finish);
+
+            b2 = decodingTable[data[i++]];
+
+            i = nextI(data, i, finish);
+
+            b3 = decodingTable[data[i++]];
+
+            i = nextI(data, i, finish);
+
+            b4 = decodingTable[data[i++]];
+
+            if ((b1 | b2 | b3 | b4) < 0) {
+                throw new IOException("invalid characters encountered in base64 data");
+            }
+
+            out.write((b1 << 2) | (b2 >> 4));
+            out.write((b2 << 4) | (b3 >> 2));
+            out.write((b3 << 6) | b4);
+
+            outLen += 3;
+
+            i = nextI(data, i, finish);
+        }
+
+        outLen += decodeLastBlock(out, (char) data[end - 4], (char) data[end - 3], (char) data[end - 2], (char) data[end - 1]);
+
+        return outLen;
+    }
+
+    private int nextI(byte[] data, int i, int finish) {
+        while ((i < finish) && ignore((char) data[i])) {
+            i++;
+        }
+        return i;
+    }
+
+    /**
+     * decode the base 64 encoded String data writing it to the given output
+     * stream, whitespace characters will be ignored.
+     *
+     * @return the number of bytes produced.
+     */
+    public int decode(String data, OutputStream out) throws IOException {
+        byte b1, b2, b3, b4;
+        int length = 0;
+
+        int end = data.length();
+
+        while (end > 0) {
+            if (!ignore(data.charAt(end - 1))) {
+                break;
+            }
+
+            end--;
+        }
+
+        int i = 0;
+        int finish = end - 4;
+
+        i = nextI(data, i, finish);
+
+        while (i < finish) {
+            b1 = decodingTable[data.charAt(i++)];
+
+            i = nextI(data, i, finish);
+
+            b2 = decodingTable[data.charAt(i++)];
+
+            i = nextI(data, i, finish);
+
+            b3 = decodingTable[data.charAt(i++)];
+
+            i = nextI(data, i, finish);
+
+            b4 = decodingTable[data.charAt(i++)];
+
+            if ((b1 | b2 | b3 | b4) < 0) {
+                throw new IOException("invalid characters encountered in base64 data");
+            }
+
+            out.write((b1 << 2) | (b2 >> 4));
+            out.write((b2 << 4) | (b3 >> 2));
+            out.write((b3 << 6) | b4);
+
+            length += 3;
+
+            i = nextI(data, i, finish);
+        }
+
+        length += decodeLastBlock(out, data.charAt(end - 4), data.charAt(end - 3), data.charAt(end - 2), data.charAt(end - 1));
+
+        return length;
+    }
+
+    private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4) throws IOException {
+        byte b1, b2, b3, b4;
+
+        if (c3 == padding) {
+            b1 = decodingTable[c1];
+            b2 = decodingTable[c2];
+
+            if ((b1 | b2) < 0) {
+                throw new IOException("invalid characters encountered at end of base64 data");
+            }
+
+            out.write((b1 << 2) | (b2 >> 4));
+
+            return 1;
+        } else if (c4 == padding) {
+            b1 = decodingTable[c1];
+            b2 = decodingTable[c2];
+            b3 = decodingTable[c3];
+
+            if ((b1 | b2 | b3) < 0) {
+                throw new IOException("invalid characters encountered at end of base64 data");
+            }
+
+            out.write((b1 << 2) | (b2 >> 4));
+            out.write((b2 << 4) | (b3 >> 2));
+
+            return 2;
+        } else {
+            b1 = decodingTable[c1];
+            b2 = decodingTable[c2];
+            b3 = decodingTable[c3];
+            b4 = decodingTable[c4];
+
+            if ((b1 | b2 | b3 | b4) < 0) {
+                throw new IOException("invalid characters encountered at end of base64 data");
+            }
+
+            out.write((b1 << 2) | (b2 >> 4));
+            out.write((b2 << 4) | (b3 >> 2));
+            out.write((b3 << 6) | b4);
+
+            return 3;
+        }
+    }
+
+    private int nextI(String data, int i, int finish) {
+        while ((i < finish) && ignore(data.charAt(i))) {
+            i++;
+        }
+        return i;
+    }
+}

+ 19 - 0
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/exception/AuthException.java

@@ -0,0 +1,19 @@
+package com.usoftchina.saas.auth.common.exception;
+
+import com.usoftchina.saas.exception.BizException;
+import com.usoftchina.saas.exception.ExceptionCode;
+
+/**
+ * @author yingp
+ * @date 2018/11/15
+ */
+public class AuthException extends BizException{
+
+    public AuthException() {
+        super(ExceptionCode.AUTH_FAIL);
+    }
+
+    public AuthException(Exception e) {
+        super(ExceptionCode.AUTH_FAIL.getCode(), e.getMessage());
+    }
+}

+ 2 - 2
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtHelper.java

@@ -30,7 +30,7 @@ public class JwtHelper {
      * @return
      * @throws Exception
      */
-    public static TokenVO generateToken(JwtInfo jwtInfo, String priKeyPath, int expire) throws BizException {
+    public static JwtToken generateToken(JwtInfo jwtInfo, String priKeyPath, int expire) throws BizException {
         try {
             String compactJws =
                     // 返回的字符串便是我们的jwt串了
@@ -47,7 +47,7 @@ public class JwtHelper {
                             .signWith(SignatureAlgorithm.RS256, RsaUtils.getPrivateKey(priKeyPath))
                             // 这个是全部设置完成后拼成jwt串的方法
                             .compact();
-            return new TokenVO(compactJws, expire);
+            return new JwtToken(compactJws, expire);
         } catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
             log.error(e.getMessage());
             throw new BizException(ExceptionCode.JWT_GEN_TOKEN_FAIL.getCode(), ExceptionCode.JWT_GEN_TOKEN_FAIL.getMessage());

+ 3 - 3
base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/TokenVO.java → base-servers/auth/auth-common/src/main/java/com/usoftchina/saas/auth/common/jwt/JwtToken.java

@@ -6,7 +6,7 @@ import java.io.Serializable;
  * @author yingp
  * @date 2018/10/2
  */
-public class TokenVO implements Serializable {
+public class JwtToken implements Serializable {
     /**
      * token
      */
@@ -18,7 +18,7 @@ public class TokenVO implements Serializable {
 
     private Long timestamp;
 
-    public TokenVO(String token, Integer expire) {
+    public JwtToken(String token, Integer expire) {
         this.token = token;
         this.expire = expire;
         this.timestamp = System.currentTimeMillis();
@@ -50,7 +50,7 @@ public class TokenVO implements Serializable {
 
     @Override
     public String toString() {
-        return "TokenVO{" +
+        return "JwtToken{" +
                 "token='" + token + '\'' +
                 ", expire=" + expire +
                 ", timestamp=" + timestamp +

+ 7 - 7
base-servers/auth/auth-server/src/main/java/com/usoftchina/saas/auth/controller/AuthController.java

@@ -5,7 +5,7 @@ import com.usoftchina.saas.account.api.AccountApi;
 import com.usoftchina.saas.account.dto.AccountDTO;
 import com.usoftchina.saas.auth.common.jwt.JwtHelper;
 import com.usoftchina.saas.auth.common.jwt.JwtInfo;
-import com.usoftchina.saas.auth.common.jwt.TokenVO;
+import com.usoftchina.saas.auth.common.jwt.JwtToken;
 import com.usoftchina.saas.auth.dto.AuthDTO;
 import com.usoftchina.saas.auth.dto.AuthorizeLogDTO;
 import com.usoftchina.saas.auth.dto.TokenDTO;
@@ -83,8 +83,8 @@ public class AuthController {
             String appId = "trade-app";
 
             JwtInfo info = new JwtInfo(appId, companyId, accountDTO.getId(), accountDTO.getUsername(), accountDTO.getRealname());
-            TokenVO tokenVO = JwtHelper.generateToken(info, privateKeyPath, expire);
-            TokenDTO tokenDTO = BeanMapper.map(tokenVO, TokenDTO.class);
+            JwtToken jwtToken = JwtHelper.generateToken(info, privateKeyPath, expire);
+            TokenDTO tokenDTO = BeanMapper.map(jwtToken, TokenDTO.class);
             // 登录日志
             authorizeLogService.save(AuthorizeLog.from(request)
                     .setAccountId(accountDTO.getId())
@@ -113,8 +113,8 @@ public class AuthController {
         if (isCompanyAvailable(infoFromToken, companyId)) {
             JwtInfo info = new JwtInfo(infoFromToken.getAppId(), companyId, infoFromToken.getUserId(),
                     infoFromToken.getUserName(), infoFromToken.getRealName());
-            TokenVO tokenVO = JwtHelper.generateToken(info, privateKeyPath, expire);
-            return Result.success(BeanMapper.map(tokenVO, TokenDTO.class));
+            JwtToken jwtToken = JwtHelper.generateToken(info, privateKeyPath, expire);
+            return Result.success(BeanMapper.map(jwtToken, TokenDTO.class));
         }
         return Result.error(ExceptionCode.COMPANY_NOT_BIND);
     }
@@ -131,8 +131,8 @@ public class AuthController {
         JwtInfo infoFromToken = JwtHelper.getInfoFromToken(token, publicKeyPath);
         Result<AccountDTO> result = accountApi.getAccount(infoFromToken.getUserName());
         if (result.isSuccess()) {
-            TokenVO tokenVO = JwtHelper.generateToken(infoFromToken, privateKeyPath, expire);
-            TokenDTO tokenDTO = BeanMapper.map(tokenVO, TokenDTO.class);
+            JwtToken jwtToken = JwtHelper.generateToken(infoFromToken, privateKeyPath, expire);
+            TokenDTO tokenDTO = BeanMapper.map(jwtToken, TokenDTO.class);
             return Result.success(new AuthDTO(tokenDTO, result.getData()));
         }
         return Result.error(result);

+ 2 - 0
framework/core/src/main/java/com/usoftchina/saas/exception/ExceptionCode.java

@@ -21,10 +21,12 @@ public enum ExceptionCode implements BaseExceptionCode {
     JWT_PARSER_TOKEN_FAIL(40005, "解析身份信息失败"),
     JWT_APPID_SECRET_INVALID(40006, "获取 access_token 时 AppSecret 错误,或者 AppId 无效!"),
     JWT_APPID_ENABLED(40007, "AppId 已经被禁用!请联系管理员"),
+    COOKIE_ILLEGAL_ARGUMENT(40010, "不合法的cookie"),
 
     // authorize相关
     AUTH_MAX_ERRORS(43001, "超过登录次数限制,账户已被冻结,请30分钟后再尝试"),
     AUTH_FROZEN(43002, "账户已被冻结,请30分钟后再尝试"),
+    AUTH_FAIL(43003, "身份验证失败"),
 
     // 账户管理相关
     COMPANY_NAME_EXIST(52000, "公司名称已注册"),