diff --git a/apollo-common/pom.xml b/apollo-common/pom.xml
index 038880b4fa68366c534dd0dfcb8c05bbaf673c82..c57a03b311ab0c494bc19def8a3fb0361bcf4616 100644
--- a/apollo-common/pom.xml
+++ b/apollo-common/pom.xml
@@ -24,11 +24,11 @@
org.springframework.boot
- spring-boot-starter-security
+ spring-boot-starter-actuator
org.springframework.boot
- spring-boot-starter-actuator
+ spring-boot-starter-security
org.springframework.cloud
diff --git a/apollo-common/src/main/java/com/ctrip/framework/apollo/common/controller/WebSecurityConfig.java b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/auth/WebSecurityConfig.java
similarity index 94%
rename from apollo-common/src/main/java/com/ctrip/framework/apollo/common/controller/WebSecurityConfig.java
rename to apollo-common/src/main/java/com/ctrip/framework/apollo/common/auth/WebSecurityConfig.java
index 3b635380d9311c7643a0a4a0d5f1cdba2d0f3c40..b85120e295e13ca32d27b94b21078e7fab12f43b 100644
--- a/apollo-common/src/main/java/com/ctrip/framework/apollo/common/controller/WebSecurityConfig.java
+++ b/apollo-common/src/main/java/com/ctrip/framework/apollo/common/auth/WebSecurityConfig.java
@@ -1,4 +1,4 @@
-package com.ctrip.framework.apollo.common.controller;
+package com.ctrip.framework.apollo.common.auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
diff --git a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/ConfigServiceTestConfiguration.java b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/ConfigServiceTestConfiguration.java
index 83728aa08c8c1b0729a1c040799a66293d63801a..ad81b9f621def4fb34f099ac0b0254b9de7f994e 100644
--- a/apollo-configservice/src/test/java/com/ctrip/framework/apollo/ConfigServiceTestConfiguration.java
+++ b/apollo-configservice/src/test/java/com/ctrip/framework/apollo/ConfigServiceTestConfiguration.java
@@ -1,6 +1,6 @@
package com.ctrip.framework.apollo;
-import com.ctrip.framework.apollo.common.controller.WebSecurityConfig;
+import com.ctrip.framework.apollo.common.auth.WebSecurityConfig;
import com.ctrip.framework.apollo.configservice.ConfigServiceApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
diff --git a/apollo-portal/pom.xml b/apollo-portal/pom.xml
index 400b5404653f78bfc358d4346c03a06cc7e69462..1408a3852ee48255acf270fcdce504bf55c815d6 100644
--- a/apollo-portal/pom.xml
+++ b/apollo-portal/pom.xml
@@ -58,4 +58,18 @@
+
+
+ ctrip
+
+ ctrip
+
+
+
+ org.jasig.cas.client
+ cas-client-core-infosec-credis
+
+
+
+
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/CtripUserInfoHolder.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/CtripUserInfoHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..19989dcd99c8661dd4123b3f4de52caf0341f03e
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/CtripUserInfoHolder.java
@@ -0,0 +1,47 @@
+package com.ctrip.framework.apollo.portal.auth;
+
+import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
+
+import java.lang.reflect.Method;
+
+/**
+ * ctrip内部实现的获取用户信息
+ */
+public class CtripUserInfoHolder implements UserInfoHolder{
+
+ private Object assertionHolder;
+
+ private Method getAssertion;
+
+
+ public CtripUserInfoHolder() {
+ Class clazz = null;
+ try {
+ clazz = Class.forName("org.jasig.cas.client.util.AssertionHolder");
+ assertionHolder = clazz.newInstance();
+ getAssertion = assertionHolder.getClass().getMethod("getAssertion");
+ } catch (Exception e) {
+ throw new RuntimeException("instance listener fail", e);
+ }
+ }
+
+ @Override
+ public UserInfo getUser() {
+ try {
+
+ Object assertion = getAssertion.invoke(assertionHolder);
+ Method getPrincipal = assertion.getClass().getMethod("getPrincipal");
+ Object principal = getPrincipal.invoke(assertion);
+ Method getName = principal.getClass().getMethod("getName");
+ String name = (String) getName.invoke(principal);
+
+ UserInfo userInfo = new UserInfo();
+ userInfo.setUsername(name);
+
+ return userInfo;
+ } catch (Exception e) {
+ throw new RuntimeException("", e);
+ }
+ }
+
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/NotCtripUserInfoHolder.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/NotCtripUserInfoHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..09c7e325d4750885cfff8e1baac7217447a40fd9
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/NotCtripUserInfoHolder.java
@@ -0,0 +1,21 @@
+package com.ctrip.framework.apollo.portal.auth;
+
+import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
+
+/**
+ * 不是ctrip的公司默认提供一个假用户
+ */
+public class NotCtripUserInfoHolder implements UserInfoHolder{
+
+
+ public NotCtripUserInfoHolder(){
+
+ }
+
+ @Override
+ public UserInfo getUser() {
+ UserInfo userInfo = new UserInfo();
+ userInfo.setUsername("apollo");
+ return userInfo;
+ }
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/UserInfoHolder.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/UserInfoHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..38ae33e044cc48e812b9fe495a48a1316d93f1f5
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/auth/UserInfoHolder.java
@@ -0,0 +1,12 @@
+package com.ctrip.framework.apollo.portal.auth;
+
+import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
+
+/**
+ * 获取登录用户的信息,不同的公司应该有不同的实现
+ */
+public interface UserInfoHolder {
+
+ UserInfo getUser();
+
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/AuthConfiguration.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/AuthConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5ba62316f0a597a04074b9e90d35cd993ee87c7
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/AuthConfiguration.java
@@ -0,0 +1,149 @@
+package com.ctrip.framework.apollo.portal.configutation;
+
+import com.ctrip.framework.apollo.portal.auth.CtripUserInfoHolder;
+import com.ctrip.framework.apollo.portal.auth.NotCtripUserInfoHolder;
+import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.FilterRegistrationBean;
+import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+
+
+/**
+ * sso相关的配置.
+ */
+@Configuration
+public class AuthConfiguration {
+
+
+ /**
+ * 在ctrip内部运行时,会指定 spring.profiles.active = ctrip.
+ * ctrip sso是通过cas实现的,所以需要加载相关的filter和listener.
+ */
+ @Configuration
+ @Profile("ctrip")
+ static class CtripProfileConfiguration{
+
+ @Autowired
+ private ServerConfigRepository serverConfigRepository;
+
+ @Bean
+ public ServletListenerRegistrationBean redisAppSettingListner(){
+ ServletListenerRegistrationBean redisAppSettingListner = new ServletListenerRegistrationBean();
+ redisAppSettingListner.setListener(listener("org.jasig.cas.client.credis.CRedisAppSettingListner"));
+ return redisAppSettingListner;
+ }
+
+ @Bean
+ public ServletListenerRegistrationBean singleSignOutHttpSessionListener(){
+ ServletListenerRegistrationBean singleSignOutHttpSessionListener = new ServletListenerRegistrationBean();
+ singleSignOutHttpSessionListener.setListener(listener("org.jasig.cas.client.session.SingleSignOutHttpSessionListener"));
+ return singleSignOutHttpSessionListener;
+ }
+
+ @Bean
+ public FilterRegistrationBean casFilter(){
+ FilterRegistrationBean singleSignOutFilter = new FilterRegistrationBean();
+ singleSignOutFilter.setFilter(filter("org.jasig.cas.client.session.SingleSignOutFilter"));
+ singleSignOutFilter.addUrlPatterns("/*");
+ return singleSignOutFilter;
+ }
+
+ @Bean
+ public FilterRegistrationBean authenticationFilter(){
+ FilterRegistrationBean casFilter = new FilterRegistrationBean();
+
+ Map filterInitParam = new HashMap();
+ filterInitParam.put("redisClusterName", "casClientPrincipal");
+ filterInitParam.put("serverName", serverConfigRepository.findByKey("serverName").getValue());
+ filterInitParam.put("casServerLoginUrl", serverConfigRepository.findByKey("casServerLoginUrl").getValue());
+
+ casFilter.setInitParameters(filterInitParam);
+ casFilter.setFilter(filter("org.jasig.cas.client.authentication.AuthenticationFilter"));
+ casFilter.addUrlPatterns("/*");
+
+ return casFilter;
+ }
+
+ @Bean
+ public FilterRegistrationBean casValidationFilter(){
+ FilterRegistrationBean casValidationFilter = new FilterRegistrationBean();
+ Map filterInitParam = new HashMap();
+ filterInitParam.put("casServerUrlPrefix", serverConfigRepository.findByKey("casServerUrlPrefix").getValue());
+ filterInitParam.put("serverName", serverConfigRepository.findByKey("serverName").getValue());
+ filterInitParam.put("encoding", "UTF-8");
+ filterInitParam.put("useRedis", "true");
+ filterInitParam.put("redisClusterName", "casClientPrincipal");
+
+ casValidationFilter.setFilter(filter("org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter"));
+ casValidationFilter.setInitParameters(filterInitParam);
+ casValidationFilter.addUrlPatterns("/*");
+
+ return casValidationFilter;
+
+ }
+
+
+
+ @Bean
+ public FilterRegistrationBean assertionHolder(){
+ FilterRegistrationBean assertionHolderFilter = new FilterRegistrationBean();
+
+ assertionHolderFilter.setFilter(filter("org.jasig.cas.client.util.AssertionThreadLocalFilter"));
+ assertionHolderFilter.addUrlPatterns("/*");
+
+ return assertionHolderFilter;
+ }
+
+ @Bean
+ public CtripUserInfoHolder ctripUserInfoHolder(){
+ return new CtripUserInfoHolder();
+ }
+
+ private Filter filter(String className){
+ Class clazz = null;
+ try {
+ clazz = Class.forName(className);
+ Object obj = clazz.newInstance();
+ return (Filter) obj;
+ } catch (Exception e) {
+ throw new RuntimeException("instance filter fail", e);
+ }
+
+ }
+
+ private EventListener listener(String className){
+ Class clazz = null;
+ try {
+ clazz = Class.forName(className);
+ Object obj = clazz.newInstance();
+ return (EventListener) obj;
+ } catch (Exception e) {
+ throw new RuntimeException("instance listener fail", e);
+ }
+ }
+ }
+
+ /**
+ * 默认实现
+ */
+ @Configuration
+ static class NotCtripProfileConfiguration{
+
+ @Bean
+ public NotCtripUserInfoHolder notCtripUserInfoHolder(){
+ return new NotCtripUserInfoHolder();
+ }
+ }
+
+
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/ServletContextConfiguration.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/ServletContextConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c4ae3e3af2a14b3253a21e14c4e47e15a34be88
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/configutation/ServletContextConfiguration.java
@@ -0,0 +1,37 @@
+package com.ctrip.framework.apollo.portal.configutation;
+
+import com.ctrip.framework.apollo.portal.entity.po.ServerConfig;
+import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.embedded.ServletContextInitializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+@Configuration
+public class ServletContextConfiguration {
+
+ @Autowired
+ private ServerConfigRepository serverConfigRepository;
+
+ @Bean
+ public ServletContextInitializer initializer(){
+
+ return new ServletContextInitializer() {
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ ServerConfig loggingServerIP = serverConfigRepository.findByKey("loggingServerIP");
+ ServerConfig loggingServerPort = serverConfigRepository.findByKey("loggingServerPort");
+ ServerConfig credisServiceUrl = serverConfigRepository.findByKey("credisServiceUrl");
+ servletContext.setInitParameter("loggingServerIP", loggingServerIP == null? "":loggingServerIP.getValue());
+ servletContext.setInitParameter("loggingServerPort", loggingServerPort == null? "":loggingServerPort.getValue());
+ servletContext.setInitParameter("credisServiceUrl", credisServiceUrl == null? "":credisServiceUrl.getValue());
+ }
+ };
+ }
+
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalAppController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalAppController.java
index 782f79de66021471103816e150620de0e5259422..183adcf7dc08e828864cdee9fb688042d35d5026 100644
--- a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalAppController.java
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalAppController.java
@@ -34,6 +34,7 @@ public class PortalAppController {
@RequestMapping("/envs/{env}")
public List findAllApp(@PathVariable String env){
+
if (StringUtils.isEmpty(env)){
throw new BadRequestException("env can not be empty");
}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalUserInfoController.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalUserInfoController.java
new file mode 100644
index 0000000000000000000000000000000000000000..47d8ddf6e65efb66046fb7a58dcb6eea3cd3ba56
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/PortalUserInfoController.java
@@ -0,0 +1,72 @@
+package com.ctrip.framework.apollo.portal.controller;
+
+import com.ctrip.framework.apollo.core.exception.BadRequestException;
+import com.ctrip.framework.apollo.portal.auth.CtripUserInfoHolder;
+import com.ctrip.framework.apollo.portal.auth.NotCtripUserInfoHolder;
+import com.ctrip.framework.apollo.portal.auth.UserInfoHolder;
+import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
+import com.ctrip.framework.apollo.portal.repository.ServerConfigRepository;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+public class PortalUserInfoController {
+ private static Logger logger = LoggerFactory.getLogger(PortalUserInfoController.class);
+
+ @Autowired
+ private ApplicationContext applicationContext;
+ @Autowired
+ private ServerConfigRepository serverConfigRepository;
+
+ private UserInfoHolder userInfoHolder;
+
+ @PostConstruct
+ public void post() {
+ try {
+ userInfoHolder = applicationContext.getBean(CtripUserInfoHolder.class);
+ } catch (NoSuchBeanDefinitionException e) {
+ logger.debug("default user info holder");
+ userInfoHolder = applicationContext.getBean(NotCtripUserInfoHolder.class);
+ }
+ }
+
+ @RequestMapping("/user")
+ public UserInfo getCurrentUserName() {
+ try {
+ return userInfoHolder.getUser();
+ } catch (Exception e) {
+ throw new BadRequestException("请先登录");
+ }
+ }
+
+ @RequestMapping("/user/logout")
+ public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ //将session销毁
+ request.getSession().invalidate();
+
+ Cookie cookie = new Cookie("memCacheAssertionID", null);
+ //将cookie的有效期设置为0,命令浏览器删除该cookie
+ cookie.setMaxAge(0);
+ cookie.setPath(request.getContextPath() + "/");
+ response.addCookie(cookie);
+
+ //重定向到SSO的logout地址
+ String casServerUrl = serverConfigRepository.findByKey("casServerUrlPrefix").getValue();
+ String serverName = serverConfigRepository.findByKey("casServerUrlPrefix").getValue();
+
+ response.sendRedirect(casServerUrl + "/logout?service=" + serverName);
+ }
+}
diff --git a/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserInfo.java b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..ded061db819d56ce3fec41ebcbe52380ecfff1ca
--- /dev/null
+++ b/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/entity/po/UserInfo.java
@@ -0,0 +1,13 @@
+package com.ctrip.framework.apollo.portal.entity.po;
+
+public class UserInfo {
+ private String username;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+}
diff --git a/apollo-portal/src/main/resources/portal.properties b/apollo-portal/src/main/resources/portal.properties
index 37ae35c18f6093837275b7a233a080e4f5fba469..454f44d9bdcec6205dc134433715ffe8893755a7 100644
--- a/apollo-portal/src/main/resources/portal.properties
+++ b/apollo-portal/src/main/resources/portal.properties
@@ -3,3 +3,5 @@ apollo.portal.envs= fat,uat,pro
ctrip.appid= 100003173
server.port= 8070
logging.file= /opt/logs/100003173/apollo-portal.log
+
+server.context_parameters.appid = ${ctrip.appid}
diff --git a/apollo-portal/src/main/resources/static/app.html b/apollo-portal/src/main/resources/static/app.html
index c805d520e43bf512da6eafa23f1467a4c0d70d8d..e4fe5b8ff16a62b23f2939d82612406b06a0362e 100644
--- a/apollo-portal/src/main/resources/static/app.html
+++ b/apollo-portal/src/main/resources/static/app.html
@@ -81,6 +81,7 @@
+
diff --git a/apollo-portal/src/main/resources/static/config.html b/apollo-portal/src/main/resources/static/config.html
index 1320dfbe666b0a5a749026a75a62df11ea301a8a..ba50f22dcd0e07f8a26ebcd397f86cd00a15eccb 100644
--- a/apollo-portal/src/main/resources/static/config.html
+++ b/apollo-portal/src/main/resources/static/config.html
@@ -609,6 +609,7 @@
+
diff --git a/apollo-portal/src/main/resources/static/config/sync.html b/apollo-portal/src/main/resources/static/config/sync.html
index 93acc0af039270ca9fe150bb37453c7cb5709f14..4f200b5a782b8096f857cc28b85990e9997f5b3f 100644
--- a/apollo-portal/src/main/resources/static/config/sync.html
+++ b/apollo-portal/src/main/resources/static/config/sync.html
@@ -190,6 +190,7 @@
+
diff --git a/apollo-portal/src/main/resources/static/namespace.html b/apollo-portal/src/main/resources/static/namespace.html
index cbffa36d5a42320c2f9a285bba7e9a4ea0faef6f..9ba8886188262a3172aadf98f8a660fc68b54d9e 100644
--- a/apollo-portal/src/main/resources/static/namespace.html
+++ b/apollo-portal/src/main/resources/static/namespace.html
@@ -105,6 +105,7 @@
+
diff --git a/apollo-portal/src/main/resources/static/scripts/directive.js b/apollo-portal/src/main/resources/static/scripts/directive.js
index 1128a9788cb0d8731225d8168e361bce79a54060..1489f28382891529279467c7a9c576642c31f657 100644
--- a/apollo-portal/src/main/resources/static/scripts/directive.js
+++ b/apollo-portal/src/main/resources/static/scripts/directive.js
@@ -1,5 +1,5 @@
/** navbar */
-directive_module.directive('apollonav', function ($compile, $window, toastr, AppUtil, AppService, EnvService) {
+directive_module.directive('apollonav', function ($compile, $window, toastr, AppUtil, AppService, EnvService, UserService) {
return {
restrict: 'E',
templateUrl: '../views/common/nav.html',
@@ -110,6 +110,12 @@ directive_module.directive('apollonav', function ($compile, $window, toastr, App
selectedAppIdx = -1;
}
+
+ UserService.load_user().then(function (result) {
+ scope.userName = result.username;
+ }, function (result) {
+
+ });
}
}
diff --git a/apollo-portal/src/main/resources/static/scripts/services/UserService.js b/apollo-portal/src/main/resources/static/scripts/services/UserService.js
new file mode 100644
index 0000000000000000000000000000000000000000..0f7a76eedddf125f82aaf346005e07758f1f736c
--- /dev/null
+++ b/apollo-portal/src/main/resources/static/scripts/services/UserService.js
@@ -0,0 +1,21 @@
+appService.service('UserService', ['$resource', '$q', function ($resource, $q) {
+ var user_resource = $resource('', {}, {
+ load_user:{
+ method: 'GET',
+ url:'/user'
+ }
+ });
+ return {
+ load_user: function () {
+ var d = $q.defer();
+ user_resource.load_user({
+ },
+ function (result) {
+ d.resolve(result);
+ }, function (result) {
+ d.reject(result);
+ });
+ return d.promise;
+ }
+ }
+}]);
diff --git a/apollo-portal/src/main/resources/static/views/common/nav.html b/apollo-portal/src/main/resources/static/views/common/nav.html
index bc34bdf1583e13c484cbb5e5fce50745bad6ab9b..509a7ce2cb668dc79102b7d723c6391ef0117ecb 100644
--- a/apollo-portal/src/main/resources/static/views/common/nav.html
+++ b/apollo-portal/src/main/resources/static/views/common/nav.html
@@ -12,9 +12,9 @@
-
用户
+ aria-expanded="false">{{userName}}
diff --git a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AbstractPortalTest.java b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AbstractPortalTest.java
index 98bcac441b4832061e0ced38bee226f3f9b2fc02..695fd00fa7f776becfd79f779e11a373b7ce6337 100644
--- a/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AbstractPortalTest.java
+++ b/apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/AbstractPortalTest.java
@@ -1,5 +1,6 @@
package com.ctrip.framework.apollo.portal;
+
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.SpringApplicationConfiguration;
@@ -25,4 +26,5 @@ public abstract class AbstractPortalTest {
@Value("${local.server.port}")
int port;
+
}
diff --git a/pom.xml b/pom.xml
index b818cea960cde3f9446be4bbbc48b292a8dfd732..9f89779df9b4faf20ce6707c5a7744799b395634 100644
--- a/pom.xml
+++ b/pom.xml
@@ -176,6 +176,11 @@
+
+ org.jasig.cas.client
+ cas-client-core-infosec-credis
+ 3.1.12
+
mysql