Commit 53f86bbb by 陶光胜

Merge branch 'developer' into 'master'

Developer

See merge request !8
parents 5e6dbb23 67734aa1
......@@ -8,6 +8,8 @@ import com.gic.enterprise.base.UserResourceInfo;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* session
* @ClassName: UserDetail

......@@ -21,13 +23,9 @@ public class UserDetail implements Serializable {
private EnterpriseInfo enterpriseInfo;
private UserResourceInfo userResourceInfo;
/**
* 用户登陆所有拥有的菜单权限,用于权限拦截
* 用户登陆所有拥有的菜单权限,用于权限拦截,存放menu_id
*/
private Map<String, Object> menuUrlMap;
private List<MenuInfo> menuInfoList;
private Map<String, MenuInfo> moduleUrlMap;
private Set<Integer> menuIdSet;
public Integer getUserId() {
return userId;
......@@ -65,27 +63,12 @@ public class UserDetail implements Serializable {
this.userResourceInfo = userResourceInfo;
}
public Map<String, Object> getMenuUrlMap() {
return menuUrlMap;
}
public void setMenuUrlMap(Map<String, Object> menuUrlMap) {
this.menuUrlMap = menuUrlMap;
}
public List<MenuInfo> getMenuInfoList() {
return menuInfoList;
}
public void setMenuInfoList(List<MenuInfo> menuInfoList) {
this.menuInfoList = menuInfoList;
}
public Map<String, MenuInfo> getModuleUrlMap() {
return moduleUrlMap;
public Set<Integer> getMenuIdSet() {
return menuIdSet;
}
public void setModuleUrlMap(Map<String, MenuInfo> moduleUrlMap) {
this.moduleUrlMap = moduleUrlMap;
public UserDetail setMenuIdSet(Set<Integer> menuIdSet) {
this.menuIdSet = menuIdSet;
return this;
}
}
......@@ -8,6 +8,7 @@ import com.gic.enterprise.context.UserContext;
import com.gic.enterprise.error.ErrorCode;
import com.gic.enterprise.exception.CommonException;
import com.gic.enterprise.utils.UserDetail;
import com.gic.redis.data.util.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.rpc.RpcContext;
......@@ -21,6 +22,9 @@ import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
* 权限拦截
......@@ -33,6 +37,8 @@ public class AuthInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = LogManager.getLogger(AuthInterceptor.class);
private static final String MENU_LOCAL_CACHE_KEY = "auth:menu:list:all";
private static final Map<String, Object> ignoreUriBeforeLoginMap = new HashMap<>(16);
private static final Map<String, Object> ignoreUriAfterLoginMap = new HashMap<>(16);
static {
......@@ -64,14 +70,6 @@ public class AuthInterceptor extends HandlerInterceptorAdapter {
//获取uri
String uri = request.getRequestURI();
log.info("权限拦截token url:{}", uri);
//操作项标志位
String isControl = request.getHeader("isControl");
//是否是操作项请求
boolean isOperationItemRequest = StringUtils.isNotBlank(isControl);
log.info("用户接口访问标志:{}", isControl);
log.info("用户接口访问路由:{}", uri);
//不需要拦截的路径
if (ignoreUriBeforeLoginMap.containsKey(uri)) {
return true;
......@@ -97,43 +95,57 @@ public class AuthInterceptor extends HandlerInterceptorAdapter {
if (ignoreUriAfterLoginMap.containsKey(uri)) {
return true;
}
//接口调用,操作项类型的操作,需要 获取操作模块,一级、二级的ID和名称
if (isOperationItemRequest) {
setOperationModule(request, userDetail);
//本地缓存数据(login的时候塞入)
Object menuLocaleCache = RedisUtil.getLocalCache(MENU_LOCAL_CACHE_KEY);
if (menuLocaleCache == null) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "sorry,您无该页面的访问权限,请联系超级管理员!");
}
List<MenuInfo> localeCacheData = (List<MenuInfo>) menuLocaleCache;
//操作模块数据
Map<String, MenuInfo> moduleMap = new HashMap<>(16);
//用户操作项数据
Map<String, MenuInfo> operationMap = new HashMap<>(16);
localeCacheData.forEach(e -> {
operationMap.put(e.getMenuId().toString(), e);
if (StringUtils.isNotBlank(e.getMenuUrl())) {
moduleMap.put(e.getProjectUrlForWeb() + e.getMenuUrl(), e);
}
});
//接口调用,操作项类型的操作,需要 获取操作模块,一级、二级的ID和名称
setOperationModule(request, localeCacheData, moduleMap);
//超级管理员不限制
if (userDetail.getUserInfo().getSuperAdmin().intValue() == 1) {
//判断是否有权限
Set<Integer> menuAuthSet = userDetail.getMenuIdSet();
if (menuAuthSet.isEmpty()) {
return true;
}
//判断是否有权限
Map<String, Object> menuUrlMap = userDetail.getMenuUrlMap();
if (menuUrlMap == null || menuUrlMap.isEmpty()) {
boolean isNoAuth = !menuAuthSet.isEmpty() && menuAuthSet.contains(-1);
if (isNoAuth) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "sorry,您无该页面的访问权限,请联系超级管理员!");
}
if (isOperationItemRequest) {
//说明是操作项
//如果匹配上了,说明是没权限
if (menuUrlMap.containsKey(uri)) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "sorry,您无该页面的访问权限,请联系超级管理员!");
}
} else {
//说明是页面
//如果没有匹配上,说明没权限
if (!menuUrlMap.containsKey(uri)) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "sorry,您无该页面的访问权限,请联系超级管理员!");
Set<String> uriSet = menuAuthSet.stream().map(e -> {
MenuInfo temp = operationMap.get(e.toString());
if (temp != null) {
return temp.getMenuUrl();
}
return "";
}).collect(Collectors.toSet());
//如果匹配上了,说明是没权限
log.info("没有权限的操作项数据:{}", JSON.toJSONString(uriSet));
if (uriSet.contains(uri)) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "sorry,您无该页面的访问权限,请联系超级管理员!");
}
return true;
}
private void setOperationModule(HttpServletRequest request, UserDetail userDetail) {
List<MenuInfo> menuInfoList = userDetail.getMenuInfoList();
Map<String, MenuInfo> moduleUrlMap = userDetail.getModuleUrlMap();
private void setOperationModule(HttpServletRequest request, List<MenuInfo> localeCacheData, Map<String, MenuInfo> moduleMap) {
//页面路径
String moduleUrl = request.getHeader("Referer");
if (StringUtils.isBlank(moduleUrl)) {
throw new CommonException(ErrorCode.SYSTEM_ERROR.getErrorCode(), "请求head中没有Referer");
}
log.info("完整路由:{}", moduleUrl);
//用于下载接口的路径
request.setAttribute("moduleMenuUrl", moduleUrl);
......@@ -141,9 +153,9 @@ public class AuthInterceptor extends HandlerInterceptorAdapter {
moduleUrl = getModuleUrl(moduleUrl);
log.info("操作模块的路由:{}", moduleUrl);
//获取当前操作项数据
MenuInfo menuInfo = moduleUrlMap.get(moduleUrl);
MenuInfo menuInfo = moduleMap.get(moduleUrl);
if (menuInfo != null) {
Map<String, MenuInfo> tempMap = listToMap(menuInfoList);
Map<String, MenuInfo> tempMap = listToMap(localeCacheData);
log.info("接口的菜单信息:{}", JSON.toJSONString(menuInfo));
Integer temp = menuInfo.getMenuId();
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.gic</groupId>
<artifactId>gic-pom-base</artifactId>
<version>4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.gic</groupId>
<artifactId>gic-enterprise-sso</artifactId>
<version>${libraryVersion}</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<libraryVersion>4.0-SNAPSHOT</libraryVersion>
</properties>
<distributionManagement>
<repository>
<!-- 和 Maven setting 保持一致 -->
<id>nexus-snapshots</id>
<name>nexus distribution snapshot repository</name>
<!-- 这里使用 /content/repositories/snapshots/ -->
<url>http://182.254.134.223:8081/nexus/content/repositories/snapshots/</url>
<!--<url>http://stream.banli.mobi:8081/content/repositories/snapshots/</url>-->
</repository>
<snapshotRepository>
<!-- 和 Maven setting 保持一致 -->
<id>nexus-snapshots</id>
<name>nexus distribution snapshot repository</name>
<!-- 这里使用 /content/repositories/snapshots/ -->
<url>http://182.254.134.223:8081/nexus/content/repositories/Snapshots-1/</url>
<!--<url>http://stream.banli.mobi:8081/content/repositories/snapshots/</url>-->
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-base-api</artifactId>
<version>${gic-base-api}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-commons</artifactId>
<version>${gic-commons}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-enterprise-base-api</artifactId>
<version>${gic-enterprise-base-api}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-platform-enterprise-api</artifactId>
<version>${gic-platform-enterprise-api}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-platform-auth-api</artifactId>
<version>${gic-platform-auth-api}</version>
</dependency>
<dependency>
<groupId>com.gic</groupId>
<artifactId>gic-platform-config</artifactId>
<version>${gic-platform-config}</version>
</dependency>
<dependency>
<groupId>com.gic.authcenter </groupId>
<artifactId>gic-authcenter-security-core </artifactId>
<version>${gic-authcenter-security-core} </version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<flattenMode>defaults</flattenMode>
</configuration>
<executions>
<!-- enable flattening -->
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<!-- ensure proper cleanup -->
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.gic.sso.utils;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.auth.dto.MenuDTO;
import com.gic.auth.dto.UserDTO;
import com.gic.auth.service.MenuApiService;
import com.gic.auth.service.UserApiService;
import com.gic.authcenter.security.core.dto.UserDetailsVO;
import com.gic.authcenter.security.core.util.UserUtils;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.enterprise.base.EnterpriseInfo;
import com.gic.enterprise.base.MenuInfo;
import com.gic.enterprise.base.UserInfo;
import com.gic.enterprise.constants.Constants;
import com.gic.enterprise.dto.EnterpriseDTO;
import com.gic.enterprise.service.EnterpriseApiService;
import com.gic.enterprise.utils.UserDetail;
import com.gic.enterprise.utils.UserDetailUtils;
import com.gic.redis.data.util.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 运维单点登录到gic后台
* @ClassName: LoginGicSsoUtils

* @Description: 

* @author guojuxing

* @date 2020/11/5 2:37 PM

*/
@Component
public class LoginGicSsoUtils {
private static Logger LOGGER = LogManager.getLogger(LoginGicSsoUtils.class);
private static LoginGicSsoUtils loginGicSsoUtils;
@Autowired
private MenuApiService menuApiService;
@Autowired
private UserApiService userApiService;
@Autowired
private EnterpriseApiService enterpriseApiService;
@PostConstruct
public void init() {
loginGicSsoUtils = this;
loginGicSsoUtils.menuApiService = menuApiService;
loginGicSsoUtils.userApiService = userApiService;
loginGicSsoUtils.enterpriseApiService = enterpriseApiService;
}
private static final String MENU_LOCAL_CACHE_KEY = "auth:menu:list:all";
/**
* 单点登录到gic
* @param enterpriseId gic商户ID
* @param redirectUrl gic后台的页面地址,前端提供,默认首页
* @return 返回跳转链接,前端直接跳转,到gic后台。如果返回null,说明错误
*/
public static String sso(Integer enterpriseId, String redirectUrl) {
long startTime = System.currentTimeMillis();
String nameSpace = "COMMON.4.0-gic-properties";
Config config = ConfigService.getConfig(nameSpace);
String url = config.getProperty("service_host", "").replace("/gic", "");
if (StringUtils.isBlank(redirectUrl)) {
redirectUrl = url + "/damo-system";
// redirectUrl = "https://four.gicdev.com/cost-center/billing-center/overview";
}
String token;
UserDetailsVO userDetailsVO = UserUtils.getUser();
String phone = userDetailsVO.getUserMobile();
//运营人员国内,默认数据
ServiceResponse<UserDTO> userResult = loginGicSsoUtils.userApiService.getUserByPhoneNumber(Constants.NATION_CODE, phone, enterpriseId);
if (userResult.isSuccess()) {
//获取运营实施信息
UserDTO user = userResult.getResult();
if (user == null) {
//新建运营实施账号
UserDTO temp = new UserDTO();
temp.setEnterpriseId(enterpriseId);
temp.setPhoneNumber(phone);
temp.setUserName(userDetailsVO.getRealName());
temp.setPhoneAreaCode(Constants.NATION_CODE);
temp.setSuperAdmin(1);
temp.setLoginType(1);
ServiceResponse<Integer> saveResult = loginGicSsoUtils.userApiService.saveOperationUser(temp);
user = temp;
user.setUserId(saveResult.getResult());
} else {
//更新运营人名称
if (!user.getUserName().equals(userDetailsVO.getRealName())) {
loginGicSsoUtils.userApiService.updateOperationUser(user.getUserId(), userDetailsVO.getRealName());
}
}
//gic用户信息塞入
UserDetail userDetail = new UserDetail();
//设置登录用户信息
userDetail.setUserId(user.getUserId());
userDetail.setUserInfo(EntityUtil.changeEntityNew(UserInfo.class, user));
//设置企业资料
ServiceResponse<EnterpriseDTO> enterprise = loginGicSsoUtils.enterpriseApiService.getEnterpriseById(enterpriseId);
if (enterprise.isSuccess()) {
EnterpriseDTO enterpriseDTO = enterprise.getResult();
if (enterpriseDTO != null) {
userDetail.setEnterpriseInfo(EntityUtil.changeEntityNew(EnterpriseInfo.class, enterpriseDTO));
}
//设置权限
ServiceResponse<List<MenuDTO>> menuResult = loginGicSsoUtils.menuApiService.listUserMenu(user.getUserId(),
enterpriseDTO.getVersionCode());
if (menuResult.isSuccess()) {
List<MenuDTO> menuList = menuResult.getResult();
Set<Integer> menuIdSet = new HashSet<>(2);
if (CollectionUtils.isNotEmpty(menuList)) {
menuIdSet = menuList.stream().filter(e -> StringUtils.isNotBlank(e.getMenuUrl()))
.map(e -> e.getMenuId()).collect(Collectors.toSet());
}
//塞用户权限菜单值
userDetail.setMenuIdSet(menuIdSet);
//塞本地缓存
setAllMenuToLocaleCache();
}
}
//塞缓存
token = UserDetailUtils.setUserDetail(userDetail);
LOGGER.info("单点登录所花时间:{}", System.currentTimeMillis() - startTime);
String ssoLoginUrl = url + "/gic-auth-web/login-for-operation";
return ssoLoginUrl + "?token=" + token + "&redirectUrl=" + redirectUrl;
}
return null;
}
/**
* gic平台的菜单数据塞本地缓存
*/
private static void setAllMenuToLocaleCache() {
ServiceResponse<List<MenuDTO>> response = loginGicSsoUtils.menuApiService.getAllMenu();
if (response.isSuccess()) {
List<MenuDTO> list = response.getResult();
//gic平台的菜单数据塞本地缓存
RedisUtil.delLocalCache(MENU_LOCAL_CACHE_KEY);
RedisUtil.setLocalCache(MENU_LOCAL_CACHE_KEY, EntityUtil.changeEntityListNew(MenuInfo.class, list), null);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.gic.sso.*"/>
<!--<dubbo:reference interface="com.gic.enterprise.service.EnterpriseApiService" id="enterpriseApiService" timeout="6000"/>-->
<!--<dubbo:reference interface="com.gic.auth.service.UserApiService" id="userApiService" timeout="6000"/>-->
<!--<dubbo:reference interface="com.gic.auth.service.MenuApiService" id="menuApiService" timeout="6000"/>-->
</beans>
......@@ -24,6 +24,7 @@
<module>gic-enterprise-base-api</module>
<module>gic-enterprise-common</module>
<module>gic-enterprise-download</module>
<module>gic-enterprise-sso</module>
</modules>
</project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment