提交 fdfd4fff 编写于 作者: L lepdou

接入sso

上级 b29fc59e
......@@ -24,11 +24,11 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
......
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;
......
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;
......
......@@ -58,4 +58,18 @@
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>ctrip</id>
<properties>
<package.environment>ctrip</package.environment>
</properties>
<dependencies>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core-infosec-credis</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
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);
}
}
}
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;
}
}
package com.ctrip.framework.apollo.portal.auth;
import com.ctrip.framework.apollo.portal.entity.po.UserInfo;
/**
* 获取登录用户的信息,不同的公司应该有不同的实现
*/
public interface UserInfoHolder {
UserInfo getUser();
}
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<String, String> 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<String, String> 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();
}
}
}
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());
}
};
}
}
......@@ -34,6 +34,7 @@ public class PortalAppController {
@RequestMapping("/envs/{env}")
public List<AppDTO> findAllApp(@PathVariable String env){
if (StringUtils.isEmpty(env)){
throw new BadRequestException("env can not be empty");
}
......
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);
}
}
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;
}
}
......@@ -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}
......@@ -81,6 +81,7 @@
<script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
<script type="application/javascript" src="scripts/directive.js"></script>
......
......@@ -609,6 +609,7 @@
<!--service-->
<script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/ConfigService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
......
......@@ -190,6 +190,7 @@
<script type="application/javascript" src="../scripts/services/AppService.js"></script>
<script type="application/javascript" src="../scripts/services/EnvService.js"></script>
<script type="application/javascript" src="../scripts/services/ConfigService.js"></script>
<script type="application/javascript" src="../scripts/services/UserService.js"></script>
<script type="application/javascript" src="../scripts/AppUtils.js"></script>
<script type="application/javascript" src="../scripts/controller/app/SyncConfigController.js"></script>
......
......@@ -105,6 +105,7 @@
<script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/services/EnvService.js"></script>
<script type="application/javascript" src="scripts/services/UserService.js"></script>
<script type="application/javascript" src="scripts/services/NamespaceService.js"></script>
<script type="application/javascript" src="scripts/AppUtils.js"></script>
......
/** 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) {
});
}
}
......
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;
}
}
}]);
......@@ -12,9 +12,9 @@
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">用户 <span class="caret"></span></a>
aria-expanded="false">{{userName}} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">退出</a></li>
<li><a href="/user/logout">退出</a></li>
</ul>
</li>
</ul>
......
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;
}
......@@ -176,6 +176,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core-infosec-credis</artifactId>
<version>3.1.12</version>
</dependency>
<!--third party -->
<dependency>
<groupId>mysql</groupId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册