diff --git a/src/main/java/com/ctrip/zeus/auth/impl/IPAuthenticationFilter.java b/src/main/java/com/ctrip/zeus/auth/impl/IPAuthenticationFilter.java index 57769dd2..ccc721f1 100644 --- a/src/main/java/com/ctrip/zeus/auth/impl/IPAuthenticationFilter.java +++ b/src/main/java/com/ctrip/zeus/auth/impl/IPAuthenticationFilter.java @@ -26,6 +26,8 @@ import java.util.Map; public class IPAuthenticationFilter implements Filter{ private static final Logger logger = LoggerFactory.getLogger(IPAuthenticationFilter.class); DynamicStringProperty ipUserStr = DynamicPropertyFactory.getInstance().getStringProperty("ip.authentication", "127.0.0.1,172.16.144.61=releaseSys"); + private static final String SLB_SERVER_USER = "slbServer"; + public static final String SERVER_TOKEN_HEADER = "SlbServerToken"; private volatile Map ipUserMap = new HashMap<>(); @@ -52,18 +54,32 @@ public class IPAuthenticationFilter implements Filter{ return; } + // check whether it is called from other slb servers. + String slbServerToken = request.getHeader(SERVER_TOKEN_HEADER); + if (slbServerToken != null){ + if (TokenManager.validateToken(slbServerToken)){ + setAssertion(request, SLB_SERVER_USER); + filterChain.doFilter(request,response); + return; + } + } + // if the request is from in ip white list, then authenticate it using the ip white list. String clientIP = getClientIP(request); String ipUser = getIpUser(clientIP); if (ipUser != null){ logger.info("Authenticated by IP: " + clientIP + " Assigned userName:" + ipUser); - assertion = new AssertionImpl(ipUser); - request.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion); - request.getSession().setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion); + setAssertion(request, ipUser); } filterChain.doFilter(request,response); } + private void setAssertion(HttpServletRequest request, String userName) { + Assertion assertion = new AssertionImpl(userName); + request.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion); + request.getSession().setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion); + } + @Override public void destroy() { // nothing to do diff --git a/src/main/java/com/ctrip/zeus/auth/impl/TokenManager.java b/src/main/java/com/ctrip/zeus/auth/impl/TokenManager.java new file mode 100644 index 00000000..7e1a1fe1 --- /dev/null +++ b/src/main/java/com/ctrip/zeus/auth/impl/TokenManager.java @@ -0,0 +1,109 @@ +package com.ctrip.zeus.auth.impl; + +import com.ctrip.zeus.dal.core.AuthPrivateKeyDao; +import com.ctrip.zeus.dal.core.AuthPrivateKeyDo; +import com.ctrip.zeus.dal.core.AuthPrivateKeyEntity; +import com.ctrip.zeus.support.DaoFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESKeySpec; +import java.security.Key; + +/** + * User: mag + * Date: 5/14/2015 + * Time: 5:27 PM + */ +public class TokenManager { + private static final Logger logger = LoggerFactory.getLogger(TokenManager.class); + public static final String ALGORITHM = "DES"; + private static String privateKey = "slbPrivateKey"; + + static { + try { + AuthPrivateKeyDao dao = new DaoFactory().getDao(AuthPrivateKeyDao.class); + AuthPrivateKeyDo privateKeyDo = dao.findFirst(AuthPrivateKeyEntity.READSET_FULL); + privateKey = privateKeyDo.getPrivateKey(); + }catch (Exception e){ + logger.error("error fetch private key from db.",e); + } + } + + public static String generateToken() { + long currTime = System.currentTimeMillis(); + byte[] timeBytes = toBytes(currTime); + try { + Key k = toKey(privateKey.getBytes("UTF-8")); + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, k); + return encryptBASE64(cipher.doFinal(timeBytes)); + }catch (Exception e){ + logger.error("error when generate token",e); + throw new RuntimeException(e); + } + } + + public static boolean validateToken(String token) { + try { + Key key = toKey(privateKey.getBytes("UTF-8")); + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, key); + long currTime = System.currentTimeMillis(); + long decryptedTime = toLong(cipher.doFinal(decryptBASE64(token))); + if ((currTime - decryptedTime) < 60000){ + return true; + } + } catch (Exception e) { + logger.error("validate token fail!",e); + } + return false; + } + + private static byte[] decryptBASE64(String key) throws Exception { + return (new BASE64Decoder()).decodeBuffer(key); + } + + + private static String encryptBASE64(byte[] key) throws Exception { + return (new BASE64Encoder()).encodeBuffer(key); + } + + private static Key toKey(byte[] key) throws Exception { + DESKeySpec dks = new DESKeySpec(key); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + SecretKey secretKey = keyFactory.generateSecret(dks); + return secretKey; + } + + private static byte[] toBytes(long value){ + byte[] result = new byte[8]; + long tmp = value; + for (int i = 7; i >= 0; i--) { + result[i] = (byte) (tmp & (0xFFL)); + tmp = tmp >> 8; + } + return result; + } + + private static long toLong(byte[] value) { + long rt = 0; + for (int i = 0; i < 8; i++) { + int add = value[i] & (0xFF); + rt = rt << 8; + rt += add; + } + return rt; + } + + public static void main(String[] args) throws Exception{ + String token = TokenManager.generateToken(); + System.out.println("token:" + token); + System.out.println("validate token:" + TokenManager.validateToken(token)); + } +} diff --git a/src/main/java/com/ctrip/zeus/client/AbstractRestClient.java b/src/main/java/com/ctrip/zeus/client/AbstractRestClient.java index 601c71de..0672e230 100644 --- a/src/main/java/com/ctrip/zeus/client/AbstractRestClient.java +++ b/src/main/java/com/ctrip/zeus/client/AbstractRestClient.java @@ -1,11 +1,16 @@ package com.ctrip.zeus.client; +import com.ctrip.zeus.auth.impl.IPAuthenticationFilter; +import com.ctrip.zeus.auth.impl.TokenManager; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.uri.UriComponent; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; /** * @author:xingchaowang @@ -28,4 +33,10 @@ public abstract class AbstractRestClient { protected WebTarget getTarget(){ return webTarget; } + + protected MultivaluedMap getDefaultHeaders(){ + MultivaluedMap map = new MultivaluedHashMap<>(); + map.putSingle(IPAuthenticationFilter.SERVER_TOKEN_HEADER, TokenManager.generateToken()); + return map; + } } diff --git a/src/main/java/com/ctrip/zeus/client/AppClient.java b/src/main/java/com/ctrip/zeus/client/AppClient.java index a6cbf0ea..13bca36f 100644 --- a/src/main/java/com/ctrip/zeus/client/AppClient.java +++ b/src/main/java/com/ctrip/zeus/client/AppClient.java @@ -20,12 +20,12 @@ public class AppClient extends AbstractRestClient { } public List getAll() { - String res = getTarget().path("/api/app").request().get(String.class); + String res = getTarget().path("/api/app").request().headers(getDefaultHeaders()).get(String.class); return null; } public Response add(App app) { - return getTarget().path("/api/app/add").request() + return getTarget().path("/api/app/add").request().headers(getDefaultHeaders()) .post(Entity.entity( String.format(App.JSON, app), MediaType.APPLICATION_JSON @@ -34,7 +34,7 @@ public class AppClient extends AbstractRestClient { } public App get(String appName) { - String res = getTarget().path("/api/app/get/" + appName).request(MediaType.APPLICATION_JSON).get(String.class); + String res = getTarget().path("/api/app/get/" + appName).request(MediaType.APPLICATION_JSON).headers(getDefaultHeaders()).get(String.class); try { return DefaultJsonParser.parse(App.class, res); } catch (IOException e) { diff --git a/src/main/java/com/ctrip/zeus/client/NginxClient.java b/src/main/java/com/ctrip/zeus/client/NginxClient.java index 87cde201..5b141e57 100644 --- a/src/main/java/com/ctrip/zeus/client/NginxClient.java +++ b/src/main/java/com/ctrip/zeus/client/NginxClient.java @@ -42,24 +42,24 @@ public class NginxClient extends AbstractRestClient { public NginxResponse load() throws IOException{ - String responseStr = getTarget().path("/api/nginx/load").request().get(String.class); + String responseStr = getTarget().path("/api/nginx/load").request().headers(getDefaultHeaders()).get(String.class); return DefaultJsonParser.parse(NginxResponse.class, responseStr); } public NginxResponse write()throws IOException{ - String responseStr = getTarget().path("/api/nginx/write").request().get(String.class); + String responseStr = getTarget().path("/api/nginx/write").request().headers(getDefaultHeaders()).get(String.class); return DefaultJsonParser.parse(NginxResponse.class, responseStr); } public NginxResponse dyups(String upsName ,String upsCommands)throws IOException{ - String responseStr = getTarget().path("/api/nginx/dyups/"+upsName).request().post(Entity.entity(upsCommands, + String responseStr = getTarget().path("/api/nginx/dyups/" + upsName).request().headers(getDefaultHeaders()).post(Entity.entity(upsCommands, MediaType.APPLICATION_JSON ),String.class); return DefaultJsonParser.parse(NginxResponse.class,responseStr); } public TrafficStatus getTrafficStatus() throws Exception { - Response response = getTarget().path("").path("/api/nginx/trafficStatus").request().get(); + Response response = getTarget().path("").path("/api/nginx/trafficStatus").request().headers(getDefaultHeaders()).get(); InputStream is = (InputStream)response.getEntity(); try { return DefaultJsonParser.parse(TrafficStatus.class, IOUtils.inputStreamStringify(is)); diff --git a/src/main/java/com/ctrip/zeus/client/SlbClient.java b/src/main/java/com/ctrip/zeus/client/SlbClient.java index 0b4c36d1..be0acafe 100644 --- a/src/main/java/com/ctrip/zeus/client/SlbClient.java +++ b/src/main/java/com/ctrip/zeus/client/SlbClient.java @@ -20,12 +20,12 @@ public class SlbClient extends AbstractRestClient { } public List getAll() { - String res = getTarget().path("/api/slb").request().get(String.class); + String res = getTarget().path("/api/slb").request().headers(getDefaultHeaders()).get(String.class); return null; } public Response add(Slb slb) { - return getTarget().path("/api/slb/add").request() + return getTarget().path("/api/slb/add").request().headers(getDefaultHeaders()) .post(Entity.entity( String.format(Slb.JSON, slb), MediaType.APPLICATION_JSON @@ -33,7 +33,7 @@ public class SlbClient extends AbstractRestClient { } public Response update(Slb slb) { - return getTarget().path("/api/slb/update").request() + return getTarget().path("/api/slb/update").request().headers(getDefaultHeaders()) .post(Entity.entity( String.format(Slb.JSON, slb), MediaType.APPLICATION_JSON @@ -41,7 +41,7 @@ public class SlbClient extends AbstractRestClient { } public Slb get(String slbName) { - String res = getTarget().path("/api/slb/get/" + slbName).request(MediaType.APPLICATION_JSON).get(String.class); + String res = getTarget().path("/api/slb/get/" + slbName).request(MediaType.APPLICATION_JSON).headers(getDefaultHeaders()).get(String.class); try { return DefaultJsonParser.parse(Slb.class, res); } catch (IOException e) { diff --git a/src/main/resources/META-INF/dal/jdbc/core-auth.xml b/src/main/resources/META-INF/dal/jdbc/core-auth.xml index 74954513..ae1743dd 100644 --- a/src/main/resources/META-INF/dal/jdbc/core-auth.xml +++ b/src/main/resources/META-INF/dal/jdbc/core-auth.xml @@ -177,5 +177,17 @@ + + + + + + FROM + ]]> + + + + diff --git a/src/main/resources/META-INF/dal/jdbc/core-codegen.xml b/src/main/resources/META-INF/dal/jdbc/core-codegen.xml index b36fae0b..c116135c 100644 --- a/src/main/resources/META-INF/dal/jdbc/core-codegen.xml +++ b/src/main/resources/META-INF/dal/jdbc/core-codegen.xml @@ -287,6 +287,42 @@ + + + + + + + + + + + + + + + + + FROM
+ WHERE = ${key-private-key}]]> + + + () + VALUES()]]> + + + + + SET + WHERE = ${key-private-key}]]> + + + + + WHERE = ${key-private-key}]]> + + + @@ -296,6 +332,7 @@ + @@ -336,6 +373,7 @@ + @@ -375,6 +413,7 @@ + @@ -407,13 +446,14 @@ - + + @@ -446,15 +486,15 @@ - - - + + + - + @@ -566,7 +606,7 @@ - + @@ -646,9 +686,11 @@ - + + + diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml index f0ee7ccb..2872cb8f 100644 --- a/src/main/resources/META-INF/plexus/components.xml +++ b/src/main/resources/META-INF/plexus/components.xml @@ -71,6 +71,15 @@ zeus + + org.unidal.dal.jdbc.mapping.TableProvider + auth-private-key + org.unidal.dal.jdbc.mapping.SimpleTableProvider + + auth_private_key + zeus + + org.unidal.dal.jdbc.mapping.TableProvider auth-resource @@ -332,6 +341,15 @@ + + com.ctrip.zeus.dal.core.AuthPrivateKeyDao + com.ctrip.zeus.dal.core.AuthPrivateKeyDao + + + org.unidal.dal.jdbc.QueryEngine + + + com.ctrip.zeus.dal.core.AuthResourceDao com.ctrip.zeus.dal.core.AuthResourceDao diff --git a/src/main/resources/META-INF/wizard/jdbc/wizard.xml b/src/main/resources/META-INF/wizard/jdbc/wizard.xml index 5848ae31..01501cdb 100644 --- a/src/main/resources/META-INF/wizard/jdbc/wizard.xml +++ b/src/main/resources/META-INF/wizard/jdbc/wizard.xml @@ -38,6 +38,7 @@
+