|
@@ -0,0 +1,295 @@
|
|
|
|
|
+package com.uas.platform.b2b.filter;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.Collection;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.HashSet;
|
|
|
|
|
+import java.util.Iterator;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.Set;
|
|
|
|
|
+
|
|
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
+
|
|
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
|
|
+import org.apache.log4j.Logger;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.mobile.device.Device;
|
|
|
|
|
+import org.springframework.mobile.device.DeviceResolver;
|
|
|
|
|
+import org.springframework.mobile.device.LiteDeviceResolver;
|
|
|
|
|
+import org.springframework.mobile.device.site.SitePreference;
|
|
|
|
|
+import org.springframework.security.access.AccessDeniedException;
|
|
|
|
|
+import org.springframework.security.access.ConfigAttribute;
|
|
|
|
|
+import org.springframework.security.access.SecurityConfig;
|
|
|
|
|
+import org.springframework.security.core.GrantedAuthority;
|
|
|
|
|
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
|
|
|
+import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
|
|
|
+
|
|
|
|
|
+import com.uas.platform.b2b.dao.ResourceItemDao;
|
|
|
|
|
+import com.uas.platform.b2b.manage.service.AccessTokenService;
|
|
|
|
|
+import com.uas.platform.b2b.model.Enterprise;
|
|
|
|
|
+import com.uas.platform.b2b.model.ResourceItem;
|
|
|
|
|
+import com.uas.platform.b2b.model.Role;
|
|
|
|
|
+import com.uas.platform.b2b.model.SigninLog;
|
|
|
|
|
+import com.uas.platform.b2b.model.User;
|
|
|
|
|
+import com.uas.platform.b2b.service.EnterpriseService;
|
|
|
|
|
+import com.uas.platform.b2b.service.RoleService;
|
|
|
|
|
+import com.uas.platform.b2b.service.SigninLogService;
|
|
|
|
|
+import com.uas.platform.b2b.service.UserService;
|
|
|
|
|
+import com.uas.platform.b2b.support.SystemSession;
|
|
|
|
|
+import com.uas.platform.b2b.support.UserCreater;
|
|
|
|
|
+import com.uas.platform.core.model.Constant;
|
|
|
|
|
+import com.uas.platform.core.util.AgentUtils;
|
|
|
|
|
+import com.uas.platform.core.util.serializer.FlexJsonUtils;
|
|
|
|
|
+import com.uas.sso.SSOHelper;
|
|
|
|
|
+import com.uas.sso.SSOToken;
|
|
|
|
|
+import com.uas.sso.web.spring.AbstractSSOInterceptor;
|
|
|
|
|
+
|
|
|
|
|
+public class SSOInterceptor extends AbstractSSOInterceptor {
|
|
|
|
|
+
|
|
|
|
|
+ private static final Logger logger = Logger.getLogger(SSOInterceptor.class);
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private UserService userService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private ResourceItemDao resourceItemDao;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private AccessTokenService accessTokenService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private EnterpriseService enterpriseService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private RoleService roleService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private SigninLogService signinLogService;
|
|
|
|
|
+
|
|
|
|
|
+ private final DeviceResolver deviceResolver = new LiteDeviceResolver();
|
|
|
|
|
+
|
|
|
|
|
+ private HashMap<String, Collection<ConfigAttribute>> resourceMap;
|
|
|
|
|
+ private HashMap<Long, Collection<GrantedAuthority>> authorities;
|
|
|
|
|
+
|
|
|
|
|
+ private User getUserByToken(SSOToken token) {
|
|
|
|
|
+ User authedUser = null;
|
|
|
|
|
+ if (token.getData() != null) {
|
|
|
|
|
+ com.uas.account.entity.User tokenUser = FlexJsonUtils.fromJson(token.getData(), com.uas.account.entity.User.class);
|
|
|
|
|
+ if (tokenUser.getUid() != null) {
|
|
|
|
|
+ // UID表示所有系统公认的唯一标识,这里统一使用手机号
|
|
|
|
|
+ authedUser = userService.findUserByUserTel(tokenUser.getUid());
|
|
|
|
|
+ } else if (tokenUser.getDialectUID() != null) {
|
|
|
|
|
+ // dialectUID表示client系统自己的唯一标识,比如user_uu,手机号没设置的情况下使用
|
|
|
|
|
+ authedUser = userService.findUserByUserUU(Long.parseLong(tokenUser.getDialectUID()));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ logger.error(String.format("invalid user %s, please set uid or dialectUID", tokenUser.getName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (authedUser != null && authedUser.getEnterprises() != null) {
|
|
|
|
|
+ // 企业资料在client系统自己的唯一标识,比如en_uu
|
|
|
|
|
+ if (tokenUser.getSpaceDialectUID() != null) {
|
|
|
|
|
+ authedUser.setCurrentEnterprise(Long.parseLong(tokenUser.getSpaceDialectUID()));
|
|
|
|
|
+ } else if (tokenUser.getSpaceUID() != null) {
|
|
|
|
|
+ for (Enterprise enterprise : authedUser.getEnterprises()) {
|
|
|
|
|
+ // 企业资料在所有系统公认的唯一标识,这里使用商业登记证号
|
|
|
|
|
+ if (tokenUser.getSpaceUID().equals(enterprise.getEnBussinessCode())) {
|
|
|
|
|
+ authedUser.setEnterprise(enterprise);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return authedUser;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected boolean onAuthenticateFailed(HttpServletRequest request, HttpServletResponse response) {
|
|
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ user = getUserByAccessToken(request);
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ user.setIp(AgentUtils.getIp(request));
|
|
|
|
|
+ request.getSession().setAttribute("user", user);
|
|
|
|
|
+ setGrantedAuthorities(user);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ SystemSession.setUser(user);
|
|
|
|
|
+ accessDecision(request, user);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected void onAuthenticateSuccess(HttpServletRequest request, HttpServletResponse response) {
|
|
|
|
|
+ User user = (User) request.getSession().getAttribute("user");
|
|
|
|
|
+ if (user == null) {
|
|
|
|
|
+ SSOToken token = SSOHelper.attrToken(request);
|
|
|
|
|
+ user = getUserByToken(token);
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ user.setIp(AgentUtils.getIp(request));
|
|
|
|
|
+ request.getSession().setAttribute("user", user);
|
|
|
|
|
+ setGrantedAuthorities(user);
|
|
|
|
|
+ log(request, user);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ SystemSession.setUser(user);
|
|
|
|
|
+ accessDecision(request, user);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 权限验证
|
|
|
|
|
+ */
|
|
|
|
|
+ private void accessDecision(HttpServletRequest request, User user) {
|
|
|
|
|
+ Collection<ConfigAttribute> configAttributes = getAttributes(request);
|
|
|
|
|
+ if (null == configAttributes || configAttributes.size() == 0 || user.isSys()) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ Iterator<ConfigAttribute> iterator = configAttributes.iterator();
|
|
|
|
|
+ String needPermission = null;
|
|
|
|
|
+ Collection<GrantedAuthority> userAuthorities = authorities.get(user.getUserUU());
|
|
|
|
|
+ while (iterator.hasNext()) {
|
|
|
|
|
+ ConfigAttribute configAttribute = iterator.next();
|
|
|
|
|
+ needPermission = configAttribute.getAttribute();
|
|
|
|
|
+ if (userAuthorities != null) {
|
|
|
|
|
+ for (GrantedAuthority ga : userAuthorities) {
|
|
|
|
|
+ if (needPermission.equals(ga.getAuthority())) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (needPermission != null)
|
|
|
|
|
+ throw new AccessDeniedException("无法访问,没有 " + needPermission + " 权限!");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
|
|
|
|
+ super.afterCompletion(request, response, handler, ex);
|
|
|
|
|
+ SystemSession.clear();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 加载资源,初始化资源变量
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+ private void loadResourceDefine() {
|
|
|
|
|
+ if (resourceMap == null) {
|
|
|
|
|
+ resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
|
|
|
|
|
+ List<ResourceItem> resources = resourceItemDao.findAll();
|
|
|
|
|
+ for (ResourceItem resource : resources) {
|
|
|
|
|
+ Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>();
|
|
|
|
|
+ ConfigAttribute configAttribute = new SecurityConfig(resource.getName());
|
|
|
|
|
+ configAttributes.add(configAttribute);
|
|
|
|
|
+ resourceMap.put(resource.getMethod() + ":" + resource.getUrl(), configAttributes);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据路径获取访问权限的集合接口
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param object
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @throws IllegalArgumentException
|
|
|
|
|
+ */
|
|
|
|
|
+ public Collection<ConfigAttribute> getAttributes(HttpServletRequest request) throws IllegalArgumentException {
|
|
|
|
|
+ if (resourceMap == null)
|
|
|
|
|
+ loadResourceDefine();
|
|
|
|
|
+
|
|
|
|
|
+ for (Iterator<String> iter = resourceMap.keySet().iterator(); iter.hasNext();) {
|
|
|
|
|
+ String resourceKey = iter.next();
|
|
|
|
|
+ String[] resourceParam = resourceKey.split(":");
|
|
|
|
|
+ String resourceMethod = resourceParam[0];
|
|
|
|
|
+ String resourceUrl = resourceParam[1];
|
|
|
|
|
+ AntPathRequestMatcher matcher = new AntPathRequestMatcher(resourceUrl);
|
|
|
|
|
+ if (null != resourceUrl && request.getMethod().equals(resourceMethod) && matcher.matches(request)) {
|
|
|
|
|
+ return resourceMap.get(resourceKey);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void setGrantedAuthorities(User user) {
|
|
|
|
|
+ Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>();
|
|
|
|
|
+ Set<Role> roles = user.getRoles();
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(roles)) {
|
|
|
|
|
+ for (Role role : roles) {
|
|
|
|
|
+ if (role.isSys()) {// 超级账号
|
|
|
|
|
+ user.setIssys(Constant.YES);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ Set<ResourceItem> resourceItems = role.getResourceItems();
|
|
|
|
|
+ if (!CollectionUtils.isEmpty(resourceItems)) {
|
|
|
|
|
+ for (ResourceItem res : resourceItems) {
|
|
|
|
|
+ authSet.add(new SimpleGrantedAuthority(res.getName()));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (authorities == null) {
|
|
|
|
|
+ authorities = new HashMap<Long, Collection<GrantedAuthority>>();
|
|
|
|
|
+ }
|
|
|
|
|
+ authorities.put(user.getUserUU(), authSet);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private final static String tokenParam = "access_token";
|
|
|
|
|
+ private final static String typeParam = "client_type";
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * access_token验证登录
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param request
|
|
|
|
|
+ */
|
|
|
|
|
+ private User getUserByAccessToken(HttpServletRequest request) {
|
|
|
|
|
+ String token = request.getParameter(tokenParam);
|
|
|
|
|
+ // 发现有采用access_token方式
|
|
|
|
|
+ if (token != null) {
|
|
|
|
|
+ Object sUser = request.getSession().getAttribute("user");
|
|
|
|
|
+ User user = null;
|
|
|
|
|
+ if (sUser != null) {
|
|
|
|
|
+ // session里面原先存在user信息,接下来要判断此user是否与token绑定的user信息一致
|
|
|
|
|
+ // 一致则跳过,无需再次验证;不一致则替换
|
|
|
|
|
+ user = (User) sUser;
|
|
|
|
|
+ }
|
|
|
|
|
+ String type = request.getParameter(typeParam);
|
|
|
|
|
+ if ("manage".equals(type)) {
|
|
|
|
|
+ if (user != null && UserCreater.isVirtual(user))
|
|
|
|
|
+ return user;
|
|
|
|
|
+ Map<String, Object> data = accessTokenService.validFormManage(token);
|
|
|
|
|
+ if (data.containsKey("user") && data.containsKey("bind")) {
|
|
|
|
|
+ long enUU = Long.parseLong(data.get("bind").toString());
|
|
|
|
|
+ Enterprise enterprise = enterpriseService.findById(enUU);
|
|
|
|
|
+ if (enterprise != null) {
|
|
|
|
|
+ List<Role> roles = roleService.findByEnterprise(enUU);
|
|
|
|
|
+ // 虚拟用户
|
|
|
|
|
+ user = UserCreater.createVirtual(String.valueOf(data.get("user")), enterprise, roles);
|
|
|
|
|
+ return user;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void log(HttpServletRequest request, User user) {
|
|
|
|
|
+ // 记录登录日志
|
|
|
|
|
+ SitePreference preference = getDefaultSitePreferenceForDevice(this.deviceResolver.resolveDevice(request));
|
|
|
|
|
+ signinLogService.save(new SigninLog(user, preference, true));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private SitePreference getDefaultSitePreferenceForDevice(Device device) {
|
|
|
|
|
+ if (device == null) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (device.isMobile()) {
|
|
|
|
|
+ return SitePreference.MOBILE;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (device.isTablet()) {
|
|
|
|
|
+ return SitePreference.TABLET;
|
|
|
|
|
+ }
|
|
|
|
|
+ return SitePreference.NORMAL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|