|
|
@@ -6,31 +6,213 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
+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.ui.ModelMap;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestMethod;
|
|
|
+import org.springframework.web.bind.annotation.ResponseBody;
|
|
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
+import com.uas.platform.b2b.model.Enterprise;
|
|
|
+import com.uas.platform.b2b.model.SigninLog;
|
|
|
+import com.uas.platform.b2b.model.User;
|
|
|
+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.core.util.AgentUtils;
|
|
|
+import com.uas.platform.core.util.serializer.FlexJsonUtils;
|
|
|
+import com.uas.sso.AuthToken;
|
|
|
+import com.uas.sso.SSOConfig;
|
|
|
import com.uas.sso.SSOHelper;
|
|
|
+import com.uas.sso.SSOToken;
|
|
|
|
|
|
@RestController
|
|
|
public class SecurityController {
|
|
|
|
|
|
+ private static final Logger logger = Logger.getLogger(SecurityController.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private UserService userService;
|
|
|
+ @Autowired
|
|
|
+ private SigninLogService signinLogService;
|
|
|
+ private final DeviceResolver deviceResolver = new LiteDeviceResolver();
|
|
|
+
|
|
|
@RequestMapping(value = "/logout", method = RequestMethod.GET, headers = "Accept=application/json")
|
|
|
@ResponseStatus(value = HttpStatus.OK)
|
|
|
- public void logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
|
|
|
+ @ResponseBody
|
|
|
+ public ModelMap logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
|
|
|
session.invalidate();
|
|
|
SSOHelper.clearLogin(request, response);
|
|
|
SystemSession.clear();
|
|
|
+ String returnUrl = request.getHeader("Referer");
|
|
|
+ boolean cross = SSOHelper.isCrossDomain(request);
|
|
|
+ if (cross) {
|
|
|
+ request.getSession().setAttribute("SSOReferer", returnUrl);
|
|
|
+ // 跨域情况,需要再次询问账户中心
|
|
|
+ returnUrl = "/logout/proxy";
|
|
|
+ }
|
|
|
+ return new ModelMap("content", returnUrl);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取跳转登录的url
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
@RequestMapping(value = "/login/page")
|
|
|
+ @ResponseBody
|
|
|
public ModelMap signin(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
|
+ request.getSession().setAttribute("SSOReferer", request.getHeader("Referer"));
|
|
|
SSOHelper.clearLogin(request, response);
|
|
|
- return new ModelMap("content", SSOHelper.getRedirectRefererLoginUrl(request));
|
|
|
+ String redirectUrl = SSOHelper.getRedirectRefererLoginUrl(request);
|
|
|
+ boolean cross = SSOHelper.isCrossDomain(request);
|
|
|
+ if (cross) {
|
|
|
+ // 跨域代理界面
|
|
|
+ redirectUrl = "/login/proxy";
|
|
|
+ }
|
|
|
+ return new ModelMap("content", redirectUrl);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取跨域登录的参数
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/login/crossBefore")
|
|
|
+ @ResponseBody
|
|
|
+ public ModelMap getCrossLoginData(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
|
+ ModelMap model = new ModelMap();
|
|
|
+ SSOConfig config = SSOHelper.getSSOService().getConfig();
|
|
|
+ // 业务系统私钥签名 authToken 自动设置临时会话 cookie 授权后自动销毁
|
|
|
+ AuthToken at = SSOHelper.askCiphertext(request, response, config.getClientPrivateKey());
|
|
|
+ // askUrl 询问 sso 是否登录地址
|
|
|
+ model.addAttribute("askUrl", config.getCrossAskUrl());
|
|
|
+ // askTxt 询问 token 密文
|
|
|
+ model.addAttribute("askData", at.encryptAuthToken());
|
|
|
+ // 未登录情况下,登录地址
|
|
|
+ Object loginUrl = null;
|
|
|
+ boolean cross = SSOHelper.isCrossDomain(request);
|
|
|
+ if (cross) {
|
|
|
+ loginUrl = SSOHelper.getRedirectRefererLoginUrl(request);
|
|
|
+ } else {
|
|
|
+ loginUrl = SSOHelper.getRedirectLoginUrl(request, String.valueOf(request.getSession().getAttribute("SSOReferer")));
|
|
|
+ }
|
|
|
+ model.addAttribute("loginUrl", loginUrl);
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 跨域登录后
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/login/crossAfter")
|
|
|
+ @ResponseBody
|
|
|
+ public ModelMap afterCrossLogin(HttpServletRequest request, HttpServletResponse response, String replyTxt) {
|
|
|
+ if (!StringUtils.isEmpty(replyTxt)) {
|
|
|
+ Object returnUrl = request.getSession().getAttribute("SSOReferer");
|
|
|
+ SSOConfig config = SSOHelper.getSSOService().getConfig();
|
|
|
+ AuthToken token = SSOHelper.ok(request, response, replyTxt, config.getClientPublicKey(), config.getCenterPublicKey());
|
|
|
+ if (token != null) {
|
|
|
+ SSOToken tk = new SSOToken();
|
|
|
+ tk.setUid(token.getUid());
|
|
|
+ tk.setTime(token.getTime());
|
|
|
+ tk.setData(token.getData());
|
|
|
+ SSOHelper.setSSOCookie(request, response, tk, true);
|
|
|
+ User user = getUserByToken(tk);
|
|
|
+ if (user != null) {
|
|
|
+ user.setIp(AgentUtils.getIp(request));
|
|
|
+ request.getSession().setAttribute("user", user);
|
|
|
+ SystemSession.setUser(user);
|
|
|
+ log(request, user);
|
|
|
+ }
|
|
|
+ return new ModelMap("returnUrl", returnUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取跨域登录的参数
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ @RequestMapping(value = "/logout/crossBefore")
|
|
|
+ @ResponseBody
|
|
|
+ public ModelMap getCrossLogoutData(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
|
|
+ ModelMap model = new ModelMap();
|
|
|
+ SSOConfig config = SSOHelper.getSSOService().getConfig();
|
|
|
+ model.addAttribute("askUrl", config.getCrossAskOutUrl());
|
|
|
+ model.addAttribute("returnUrl", String.valueOf(request.getSession().getAttribute("SSOReferer")));
|
|
|
+ return model;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
|
}
|