diff --git a/JSD-7957-需求文档V3.docx b/JSD-7957-需求文档V3.docx
new file mode 100644
index 0000000..734b4e5
Binary files /dev/null and b/JSD-7957-需求文档V3.docx differ
diff --git a/README.md b/README.md
index 357bb20..2eea1c0 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
# open-JSD-7957
-jsd-7957 开源材料
\ No newline at end of file
+jsd-7957 开源材料\
+免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
+仅作为开发者学习参考使用!禁止用于任何商业用途!\
+为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。
\ No newline at end of file
diff --git a/conf.properties b/conf.properties
new file mode 100644
index 0000000..ea9ce39
--- /dev/null
+++ b/conf.properties
@@ -0,0 +1,12 @@
+#¼ͳһַ
+auth_url=
+#ȡtokanַ
+token_url=
+#ȡûϢ
+user_url=
+#client_id
+client_id=
+#client_secret
+client_secret=
+#dzתַ
+logout=
\ No newline at end of file
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..4ae0721
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,21 @@
+
+ com.fr.plugin.sxka.sso
+
+ yes
+ 1.9
+ 10.0
+ 2018-07-31
+ fr.open
+
+ -->
+ ]]>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/sxka/sso/CustomLogInOutEventProvider.java b/src/main/java/com/fr/plugin/sxka/sso/CustomLogInOutEventProvider.java
new file mode 100644
index 0000000..5b2ec5d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sxka/sso/CustomLogInOutEventProvider.java
@@ -0,0 +1,40 @@
+package com.fr.plugin.sxka.sso;
+
+import com.fr.decision.fun.impl.AbstractLogInOutEventProvider;
+import com.fr.decision.webservice.login.LogInOutResultInfo;
+import com.fr.decision.webservice.utils.DecisionStatusService;
+import com.fr.general.PropertiesUtils;
+import com.fr.log.FineLoggerFactory;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @Author fr.open
+ * @Date 2020/9/18
+ * @Description
+ **/
+public class CustomLogInOutEventProvider extends AbstractLogInOutEventProvider {
+ @Override
+ public String logoutAction(LogInOutResultInfo result) {
+ String state = getUserStateFromCookie(result.getRequest());
+ try {
+ DecisionStatusService.loginStatusService().delete(state);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ String logout = PropertiesUtils.getProperties("conf").getProperty("logout");
+ String format = "%s?client_id=%s&callback=%s&state=%s";
+ return String.format(format, logout, PropertiesUtils.getProperties("conf").getProperty("client_id"), PropertiesUtils.getProperties("conf").getProperty("redirect_uri"),state);
+ }
+
+ private String getUserStateFromCookie(HttpServletRequest request) {
+ if (request.getCookies() == null) return null;
+
+ for (Cookie cookie : request.getCookies()) {
+ if ("uid_state".equals(cookie.getName())) return cookie.getValue();
+ }
+ return null;
+ }
+
+}
diff --git a/src/main/java/com/fr/plugin/sxka/sso/RoleDBAccessProvider.java b/src/main/java/com/fr/plugin/sxka/sso/RoleDBAccessProvider.java
new file mode 100644
index 0000000..9210b1d
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sxka/sso/RoleDBAccessProvider.java
@@ -0,0 +1,44 @@
+package com.fr.plugin.sxka.sso;
+
+import com.fr.db.fun.impl.AbstractDBAccessProvider;
+import com.fr.plugin.sxka.sso.dao.UserInfoDao;
+import com.fr.plugin.sxka.sso.entity.UserInfoEntity;
+import com.fr.stable.db.accessor.DBAccessor;
+import com.fr.stable.db.dao.BaseDAO;
+import com.fr.stable.db.dao.DAOProvider;
+
+/**
+ * @Author fr.open
+ * @Date 2021/5/13
+ * @Description
+ **/
+public class RoleDBAccessProvider extends AbstractDBAccessProvider {
+
+ private static DBAccessor dbAccessor = null;
+
+ public static DBAccessor getDbAccessor() {
+ return dbAccessor;
+ }
+
+ @Override
+ public DAOProvider[] registerDAO() {
+ return new DAOProvider[]{
+ new DAOProvider() {
+ @Override
+ public Class getEntityClass() {
+ return UserInfoEntity.class;
+ }
+
+ @Override
+ public Class extends BaseDAO> getDAOClass() {
+ return UserInfoDao.class;
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onDBAvailable(DBAccessor dbAccessor) {
+ RoleDBAccessProvider.dbAccessor = dbAccessor;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/sxka/sso/SsoFilter.java b/src/main/java/com/fr/plugin/sxka/sso/SsoFilter.java
new file mode 100644
index 0000000..4c41a4a
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sxka/sso/SsoFilter.java
@@ -0,0 +1,493 @@
+package com.fr.plugin.sxka.sso;
+
+import com.fr.base.PropertiesUtils;
+import com.fr.data.NetworkHelper;
+import com.fr.decision.authority.AuthorityContext;
+import com.fr.decision.authority.data.CustomRole;
+import com.fr.decision.authority.data.User;
+import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+import com.fr.decision.mobile.terminal.TerminalHandler;
+import com.fr.decision.webservice.bean.authentication.OriginUrlResponseBean;
+import com.fr.decision.webservice.bean.user.UserBean;
+import com.fr.decision.webservice.exception.user.UserNotExistException;
+import com.fr.decision.webservice.utils.DecisionServiceConstants;
+import com.fr.decision.webservice.utils.DecisionStatusService;
+import com.fr.decision.webservice.utils.WebServiceUtils;
+import com.fr.decision.webservice.v10.login.LoginService;
+import com.fr.decision.webservice.v10.login.TokenResource;
+import com.fr.decision.webservice.v10.user.UserService;
+import com.fr.general.http.HttpRequest;
+import com.fr.general.http.HttpToolbox;
+import com.fr.json.JSONObject;
+import com.fr.json.revise.EmbedJson;
+import com.fr.locale.InterProviderFactory;
+import com.fr.log.FineLoggerFactory;
+import com.fr.plugin.sxka.sso.dao.UserInfoDao;
+import com.fr.plugin.sxka.sso.entity.UserInfoEntity;
+import com.fr.plugin.transform.FunctionRecorder;
+import com.fr.security.encryption.transmission.TransmissionEncryptors;
+import com.fr.stable.StringUtils;
+import com.fr.stable.db.action.DBAction;
+import com.fr.stable.db.dao.DAOContext;
+import com.fr.stable.query.QueryFactory;
+import com.fr.stable.query.restriction.RestrictionFactory;
+import com.fr.stable.web.Device;
+import com.fr.third.fasterxml.jackson.databind.DeserializationFeature;
+import com.fr.third.fasterxml.jackson.databind.ObjectMapper;
+import com.fr.third.springframework.http.HttpHeaders;
+import com.fr.third.springframework.http.MediaType;
+import com.fr.third.springframework.util.DigestUtils;
+import com.fr.web.controller.decision.api.auth.LoginResource;
+import com.fr.web.utils.WebUtils;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @Author fr.open
+ * @Date 2021/5/12
+ * @Description
+ **/
+@FunctionRecorder
+public class SsoFilter extends AbstractGlobalRequestFilterProvider {
+
+ private static String[] notFilter = {
+ "/login",
+ "/system", "/decision/file",
+ "/decision/resources", "/remote","/view/report"
+ };
+ private static HashMap ROLE_MAP;
+
+ static {
+ ROLE_MAP = new HashMap<>();
+ ROLE_MAP.put("1", "企业管理员");
+ ROLE_MAP.put("2", "个人用户");
+ ROLE_MAP.put("3", "企业操作员");
+ ROLE_MAP.put("4", "政府端用户");
+ }
+
+ @Override
+ public String filterName() {
+ return "sxka";
+ }
+
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{"/*"};
+ }
+
+ @Override
+ public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ if(req.getRequestURI().endsWith("/test/error")){
+ setError(res);
+ return;
+ }
+ if (req.getRequestURI().endsWith("/admin/login")) {
+ try {
+ String page = new LoginResource().page(req, res);
+ if (StringUtils.isBlank(page)) {
+ return;
+ }
+ PrintWriter writer = WebUtils.createPrintWriter(res);
+ writer.println(page);
+ writer.flush();
+ writer.close();
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return;
+ }
+ //登录页面跳转地址拦截
+ String origin = WebUtils.getHTTPRequestParameter(req, "origin");
+ if (req.getRequestURI().endsWith("decision/login") && "get".equalsIgnoreCase(req.getMethod())) {
+ String state = this.getUserStateFromCookie(req, res);
+
+ try {
+ if (StringUtils.isNotBlank(origin)) {
+ OriginUrlResponseBean path = DecisionStatusService.originUrlStatusService().get(origin);
+ cacheParam(res, path.getOriginUrl());
+ }
+ res.sendRedirect(buildAuthorizeUrl(state));
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+ if (isLogin(req) || isAccept(req)) {
+ filter(req, res, filterChain);
+ return;
+ }
+ String state = this.getUserStateFromCookie(req, res);
+ String code = req.getParameter("code");
+ if (StringUtils.isNotBlank(code)) {
+ JSONObject data = acquireAccessToken(code);
+ FineLoggerFactory.getLogger().info("get access_token is {}", data);
+ // 计算过期时间
+ int expires = Integer.valueOf(data.get("expires_in").toString());
+ Date expiresTime = new Date(System.currentTimeMillis() + (expires * 1000));
+ data.put("expires_at", expiresTime);
+ // 保存关系映射
+ putState(state, data);
+ }
+ JSONObject tokenItem = null;
+ try {
+ tokenItem = DecisionStatusService.loginStatusService().get(state);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ if (tokenItem == null) {
+ try {
+ String jump = req.getRequestURL() + (req.getQueryString() == null ? StringUtils.EMPTY : "?" + req.getQueryString());
+ cacheParam(res, jump);
+ res.sendRedirect(buildAuthorizeUrl(state));
+ return;
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+ // 用检查 access token 是否过期
+ Date tokenExpiresAt = (Date) tokenItem.get("expires_at");
+ Date now = new Date();
+ if (tokenExpiresAt.before(now)) {
+ // 使用 refresh token 刷新 access token
+ String refreshToken = tokenItem.get("refresh_token").toString();
+ tokenItem = this.refreshToken(refreshToken);
+ putState(state, tokenItem);
+ }
+ String accessToken = tokenItem.get("access_token").toString();
+ JSONObject userProfile = this.acquireUserInfo(state, accessToken);
+ try {
+ if (!existUser(userProfile.getString("id"))) {
+ FineLoggerFactory.getLogger().info("user {} not exist ", userProfile.getString("id"));
+ UserBean userBean = new UserBean();
+ userBean.setUsername(userProfile.getString("id"));
+ userBean.setRealName(userProfile.getString("op_name"));
+ userBean.setEnable(true);
+ userBean.setPassword(TransmissionEncryptors.getInstance().encrypt("!234Qwer"));
+ UserService.getInstance().addUser(userBean);
+ }
+ UserInfoEntity infoEntity = recordUserInfo(userProfile);
+ if(checkAuth(infoEntity, req, res)){
+ return;
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ filter(req, res, filterChain);
+ }
+
+ private void putState(String state, JSONObject data) {
+ try {
+ DecisionStatusService.loginStatusService().put(state, data);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(),e);
+ }
+ }
+
+ private void cacheParam(HttpServletResponse res, String jump) {
+ String id = UUID.randomUUID().toString();
+ try {
+ DecisionStatusService.originUrlStatusService().put(id, new OriginUrlResponseBean(jump));//添加重定向地址
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ Cookie cookie = new Cookie("ORIGIN_URL", id);
+ cookie.setPath("/");
+ cookie.setMaxAge(60);
+ cookie.setHttpOnly(true);
+ res.addCookie(cookie);
+ }
+
+ private boolean checkAuth(UserInfoEntity entity, HttpServletRequest req, HttpServletResponse res) throws Exception {
+ if (StringUtils.isNotBlank(entity.getStatus()) && entity.getStatus().equalsIgnoreCase("true")) {
+ if (entity.getAccount_type().equals("1") || entity.getAccount_type().equals("3") || entity.getAccount_type().equals("4")) {
+ UserBean userAccount = UserService.getInstance().getUserAccount(entity.getId());
+ String roleName = ROLE_MAP.containsKey(entity.getAccount_type()) ? ROLE_MAP.get(entity.getAccount_type()) : "其他";
+ CustomRole role = AuthorityContext.getInstance().getCustomRoleController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("name", roleName)));
+ if (role != null) {
+ List oldRoleList = AuthorityContext.getInstance().getCustomRoleController().findByUser(userAccount.getId(), QueryFactory.create());
+ oldRoleList.forEach(e->{
+ try {
+ AuthorityContext.getInstance().getUserController().removeUserFromCustomRole(userAccount.getId(), e.getId());
+ } catch (Exception exception) {
+ FineLoggerFactory.getLogger().error(exception.getMessage(),exception);
+ }
+ });
+ AuthorityContext.getInstance().getUserController().addUserToCustomRole(userAccount.getId(),role.getId());
+ }
+ }
+ loginFromToken(req, res, entity.getId());
+ String jump = getOrigin(req);
+ FineLoggerFactory.getLogger().info("get Origin path is {}", jump);
+ if (StringUtils.isNotBlank(jump)) {
+ res.sendRedirect(jump);
+ return true;
+ }
+ return false;
+ }
+ if(entity.getAccount_type().equals("1") || entity.getAccount_type().equals("3") || entity.getAccount_type().equals("4")){
+ setError(res);
+ return true;
+ }
+ String url = PropertiesUtils.getProperties("conf").getProperty("write_report");
+ String param = "username="+ URLEncoder.encode(entity.getOp_name(),"UTF-8")+"&id="+entity.getId();
+ url = url.indexOf("?") != -1?url+"&"+param:url+"?"+param;
+ res.sendRedirect(url);
+ return true;
+ }
+
+
+
+ private String getOrigin(HttpServletRequest req) throws Exception {
+ Cookie[] cookies = req.getCookies();
+ if (cookies == null) {
+ return null;
+ }
+ for (int i = 0; i < cookies.length; i++) {
+ if ("ORIGIN_URL".equals(cookies[i].getName())) {
+ String id = cookies[i].getValue();
+ OriginUrlResponseBean path = DecisionStatusService.originUrlStatusService().get(id);
+ if (path != null) {
+ DecisionStatusService.originUrlStatusService().delete(id);
+ return path.getOriginUrl();
+ }
+ }
+ }
+ return StringUtils.EMPTY;
+ }
+
+ private UserInfoEntity recordUserInfo(JSONObject user) {
+ ObjectMapper mapper = EmbedJson.MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ UserInfoEntity entity = mapper.convertValue(user, UserInfoEntity.class);
+ try {
+ return RoleDBAccessProvider.getDbAccessor().runDMLAction(new DBAction() {
+ @Override
+ public UserInfoEntity run(DAOContext daoContext) throws Exception {
+ UserInfoDao dao = daoContext.getDAO(UserInfoDao.class);
+ UserInfoEntity byId = dao.getById(entity.getId());
+ if (byId != null) {
+ entity.setStatus(byId.getStatus());
+ entity.setAccount_type(byId.getAccount_type());
+ } else {
+ entity.setStatus("false");
+ }
+ dao.addOrUpdate(entity);
+ return entity;
+ }
+ });
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return entity;
+
+ }
+
+ private boolean existUser(String username) {
+ User user = null;
+ try {
+ user = UserService.getInstance().getUserByUserName(username);
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return user != null;
+ }
+
+ private boolean loginFromToken(HttpServletRequest req, HttpServletResponse res, String username) throws Exception {
+ try {
+ if (StringUtils.isNotEmpty(username)) {
+ FineLoggerFactory.getLogger().info("current username:" + username);
+ User user = UserService.getInstance().getUserByUserName(username);
+ FineLoggerFactory.getLogger().info("get user:" + user);
+ if (user == null) {
+ throw new UserNotExistException();
+ }
+ String token = LoginService.getInstance().login(req, res, username);
+ FineLoggerFactory.getLogger().info("get login token:" + token);
+ req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, token);
+ FineLoggerFactory.getLogger().info("username:" + username + "login success");
+ return true;
+ } else {
+ FineLoggerFactory.getLogger().warn("username is null!");
+ return false;
+ }
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return false;
+ }
+
+
+ private JSONObject acquireUserInfo(String state, String accessToken) {
+ String url = PropertiesUtils.getProperties("conf").getProperty("user_url");
+
+ Map params = new HashMap<>();
+ params.put("client_id", PropertiesUtils.getProperties("conf").getProperty("client_id"));
+ params.put("access_token", accessToken);
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ try {
+ String res = HttpToolbox.executeAndParse(HttpRequest.custom().url(url)
+ .headers(headers.toSingleValueMap())
+ .post(params)
+ .build());
+ FineLoggerFactory.getLogger().info("get user name url is 【{}】,params is,{} res is {}", url, params, res);
+ JSONObject object = new JSONObject(res);
+ return object.getJSONObject("data");
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return JSONObject.EMPTY;
+ }
+
+ private JSONObject refreshToken(String refreshToken) {
+ String url = PropertiesUtils.getProperties("conf").getProperty("token_url");
+
+ Map params = new HashMap<>();
+ params.put("grant_type", "refresh_token");
+ params.put("refresh_token", refreshToken);
+ params.put("client_id", PropertiesUtils.getProperties("conf").getProperty("client_id"));
+ params.put("client_sign", this.makeSign(refreshToken));
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ try {
+ String res = HttpToolbox.executeAndParse(HttpRequest.custom().url(url)
+ .headers(headers.toSingleValueMap())
+ .post(params)
+ .build());
+ FineLoggerFactory.getLogger().info("get refresh token url is 【{}】,params is,{} res is {}", url, params, res);
+ JSONObject object = new JSONObject(res);
+ return object.getJSONObject("data");
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return JSONObject.EMPTY;
+ }
+
+ private JSONObject acquireAccessToken(String code) {
+ String url = PropertiesUtils.getProperties("conf").getProperty("token_url");
+ Map params = new HashMap<>();
+ params.put("grant_type", "authorization_code");
+ params.put("code", code);
+ params.put("client_id", PropertiesUtils.getProperties("conf").getProperty("client_id"));
+ params.put("client_sign", this.makeSign(code));
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ try {
+ String res = HttpToolbox.executeAndParse(HttpRequest.custom().url(url)
+ .headers(headers.toSingleValueMap())
+ .post(params)
+ .build());
+ FineLoggerFactory.getLogger().info("get access token url is 【{}】,params is,{} res is {}", url, params, res);
+ JSONObject object = new JSONObject(res);
+ return object.getJSONObject("data");
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ return JSONObject.EMPTY;
+ }
+
+ /**
+ * 生成签名值= md5Hex("$$", UTF8)
+ *
+ * @param data
+ * @return
+ */
+ private String makeSign(String data) {
+ String value = String.join("$", new String[]{
+ PropertiesUtils.getProperties("conf").getProperty("client_id"),
+ data,
+ PropertiesUtils.getProperties("conf").getProperty("client_secret")
+ });
+ return DigestUtils.md5DigestAsHex(value.getBytes(StandardCharsets.UTF_8));
+ }
+
+ private String buildAuthorizeUrl(String state) {
+ String format = "%s?client_id=%s&response_type=code&scope=A1,C1,C2&state=%s&redirect_uri=%s";
+ return String.format(format, PropertiesUtils.getProperties("conf").getProperty("auth_url"), PropertiesUtils.getProperties("conf").getProperty("client_id"), state, PropertiesUtils.getProperties("conf").getProperty("redirect_uri"));
+ }
+
+ private void setUserStateCookie(HttpServletResponse response, String state) {
+ Cookie cookie = new Cookie("uid_state", state);
+ cookie.setMaxAge(300);
+ // 正式环境采用HTTPS协议,需要取消下方注释,确保仅在HTTPS下可用
+// cookie.setSecure(true);
+ cookie.setPath("/");
+ response.addCookie(cookie);
+ }
+
+ private String getUserStateFromCookie(HttpServletRequest request, HttpServletResponse res) {
+ if (request.getCookies() == null) return null;
+
+ String state = StringUtils.EMPTY;
+ for (Cookie cookie : request.getCookies()) {
+ if ("uid_state".equals(cookie.getName())) {
+ state = cookie.getValue();
+ }
+ }
+ if (StringUtils.isBlank(state)) {
+ state = UUID.randomUUID().toString();
+ this.setUserStateCookie(res, state);
+ }
+ return state;
+ }
+
+ private boolean isAccept(HttpServletRequest req) {
+ for (int i = 0; i < notFilter.length; i++) {
+ if (req.getRequestURI().contains(notFilter[i])) {
+ return true;
+ }
+ }
+ if (req.getRequestURI().endsWith("/.css") || req.getRequestURI().endsWith("/.css")) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isLogin(HttpServletRequest request) {
+ String oldToken = TokenResource.COOKIE.getToken(request);
+ return oldToken != null && checkTokenValid(request, (String) oldToken);
+ }
+
+ private boolean checkTokenValid(HttpServletRequest req, String token) {
+ try {
+ Device device = NetworkHelper.getDevice(req);
+ LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device));
+ return true;
+ } catch (Exception ignore) {
+ }
+ return false;
+ }
+
+ private void setError(HttpServletResponse res) {
+ try {
+ PrintWriter printWriter = WebUtils.createPrintWriter(res);
+ Map map = new HashMap<>();
+ map.put("result", InterProviderFactory.getProvider().getLocText("Fine-Engine_Error_Page_Result"));
+ map.put("reason", "当前用户已冻结,请联系系统管理员激活");
+ map.put("solution", InterProviderFactory.getProvider().getLocText("Fine-Engine_Please_Contact_Platform_Admin"));
+ String page = WebServiceUtils.parseWebPageResourceSafe("com/fr/web/controller/decision/entrance/resources/unavailable.html", map);
+ printWriter.write(page);
+ printWriter.flush();
+ printWriter.close();
+ } catch (Exception e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+
+ private void filter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) {
+ try {
+ filterChain.doFilter(req, res);
+ } catch (IOException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ } catch (ServletException e) {
+ FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ }
+ }
+}
diff --git a/src/main/java/com/fr/plugin/sxka/sso/dao/UserInfoDao.java b/src/main/java/com/fr/plugin/sxka/sso/dao/UserInfoDao.java
new file mode 100644
index 0000000..de14429
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sxka/sso/dao/UserInfoDao.java
@@ -0,0 +1,21 @@
+package com.fr.plugin.sxka.sso.dao;
+
+import com.fr.plugin.sxka.sso.entity.UserInfoEntity;
+import com.fr.stable.db.dao.BaseDAO;
+import com.fr.stable.db.session.DAOSession;
+
+/**
+ * @Author fr.open
+ * @Date 2021/5/17
+ * @Description
+ **/
+public class UserInfoDao extends BaseDAO {
+ public UserInfoDao(DAOSession daoSession) {
+ super(daoSession);
+ }
+
+ @Override
+ protected Class getEntityClass() {
+ return UserInfoEntity.class;
+ }
+}
diff --git a/src/main/java/com/fr/plugin/sxka/sso/entity/UserInfoEntity.java b/src/main/java/com/fr/plugin/sxka/sso/entity/UserInfoEntity.java
new file mode 100644
index 0000000..45d06bc
--- /dev/null
+++ b/src/main/java/com/fr/plugin/sxka/sso/entity/UserInfoEntity.java
@@ -0,0 +1,297 @@
+package com.fr.plugin.sxka.sso.entity;
+
+import com.fr.stable.db.entity.BaseEntity;
+import com.fr.third.javax.persistence.Column;
+import com.fr.third.javax.persistence.Entity;
+import com.fr.third.javax.persistence.Table;
+
+/**
+ * @Author fr.open
+ * @Date 2021/5/13
+ * @Description
+ **/
+@Entity
+@Table(name = "plugin_sxka_user_info")
+public class UserInfoEntity extends BaseEntity {
+
+ private static final long serialVersionUID = 5278704449983309952L;
+
+ @Column(name = "op_name")
+ private String op_name;
+
+ @Column(name = "organization")
+ private String organization;
+
+ @Column(name = "account_type")
+ private String account_type;
+
+ @Column(name = "login_type")
+ private String login_type;
+
+ @Column(name = "gs_name")
+ private String gs_name;
+
+ @Column(name = "gs_name_en")
+ private String gs_name_en;
+
+ @Column(name = "gs_type")
+ private String gs_type;
+
+ @Column(name = "gs_address")
+ private String gs_address;
+
+ @Column(name = "gs_address_en")
+ private String gs_address_en;
+
+ @Column(name = "gs_tax_code")
+ private String gs_tax_code;
+
+ @Column(name = "gs_expires")
+ private String gs_expires;
+
+ @Column(name = "gs_postcode")
+ private String gs_postcode;
+
+ @Column(name = "gs_scope")
+ private String gs_scope;
+
+ @Column(name = "gs_status")
+ private String gs_status;
+
+ @Column(name = "gs_regcap")
+ private String gs_regcap;
+
+ @Column(name = "gs_regcap_cur")
+ private String gs_regcap_cur;
+
+ @Column(name = "gs_social_credit_code")
+ private String gs_social_credit_code;
+
+ @Column(name = "gs_code")
+ private String gs_code;
+
+ @Column(name = "gs_regorg")
+ private String gs_regorg;
+
+ @Column(name = "gs_reg_number")
+ private String gs_reg_number;
+
+ @Column(name = "gs_location")
+ private String gs_location;
+
+ @Column(name = "cus_number")
+ private String cus_number;
+
+ @Column(name = "cus_expires")
+ private String cus_expires;
+
+ @Column(name = "cus_master")
+ private String cus_master;
+
+ @Column(name = "status")
+ private String status;
+
+ public static long getSerialVersionUID() {
+ return serialVersionUID;
+ }
+
+ public String getOp_name() {
+ return op_name;
+ }
+
+ public void setOp_name(String op_name) {
+ this.op_name = op_name;
+ }
+
+ public String getOrganization() {
+ return organization;
+ }
+
+ public void setOrganization(String organization) {
+ this.organization = organization;
+ }
+
+ public String getAccount_type() {
+ return account_type;
+ }
+
+ public void setAccount_type(String account_type) {
+ this.account_type = account_type;
+ }
+
+ public String getLogin_type() {
+ return login_type;
+ }
+
+ public void setLogin_type(String login_type) {
+ this.login_type = login_type;
+ }
+
+ public String getGs_name() {
+ return gs_name;
+ }
+
+ public void setGs_name(String gs_name) {
+ this.gs_name = gs_name;
+ }
+
+ public String getGs_name_en() {
+ return gs_name_en;
+ }
+
+ public void setGs_name_en(String gs_name_en) {
+ this.gs_name_en = gs_name_en;
+ }
+
+ public String getGs_type() {
+ return gs_type;
+ }
+
+ public void setGs_type(String gs_type) {
+ this.gs_type = gs_type;
+ }
+
+ public String getGs_address() {
+ return gs_address;
+ }
+
+ public void setGs_address(String gs_address) {
+ this.gs_address = gs_address;
+ }
+
+ public String getGs_address_en() {
+ return gs_address_en;
+ }
+
+ public void setGs_address_en(String gs_address_en) {
+ this.gs_address_en = gs_address_en;
+ }
+
+ public String getGs_tax_code() {
+ return gs_tax_code;
+ }
+
+ public void setGs_tax_code(String gs_tax_code) {
+ this.gs_tax_code = gs_tax_code;
+ }
+
+ public String getGs_expires() {
+ return gs_expires;
+ }
+
+ public void setGs_expires(String gs_expires) {
+ this.gs_expires = gs_expires;
+ }
+
+ public String getGs_postcode() {
+ return gs_postcode;
+ }
+
+ public void setGs_postcode(String gs_postcode) {
+ this.gs_postcode = gs_postcode;
+ }
+
+ public String getGs_scope() {
+ return gs_scope;
+ }
+
+ public void setGs_scope(String gs_scope) {
+ this.gs_scope = gs_scope;
+ }
+
+ public String getGs_status() {
+ return gs_status;
+ }
+
+ public void setGs_status(String gs_status) {
+ this.gs_status = gs_status;
+ }
+
+ public String getGs_regcap() {
+ return gs_regcap;
+ }
+
+ public void setGs_regcap(String gs_regcap) {
+ this.gs_regcap = gs_regcap;
+ }
+
+ public String getGs_regcap_cur() {
+ return gs_regcap_cur;
+ }
+
+ public void setGs_regcap_cur(String gs_regcap_cur) {
+ this.gs_regcap_cur = gs_regcap_cur;
+ }
+
+ public String getGs_social_credit_code() {
+ return gs_social_credit_code;
+ }
+
+ public void setGs_social_credit_code(String gs_social_credit_code) {
+ this.gs_social_credit_code = gs_social_credit_code;
+ }
+
+ public String getGs_code() {
+ return gs_code;
+ }
+
+ public void setGs_code(String gs_code) {
+ this.gs_code = gs_code;
+ }
+
+ public String getGs_regorg() {
+ return gs_regorg;
+ }
+
+ public void setGs_regorg(String gs_regorg) {
+ this.gs_regorg = gs_regorg;
+ }
+
+ public String getGs_reg_number() {
+ return gs_reg_number;
+ }
+
+ public void setGs_reg_number(String gs_reg_number) {
+ this.gs_reg_number = gs_reg_number;
+ }
+
+ public String getGs_location() {
+ return gs_location;
+ }
+
+ public void setGs_location(String gs_location) {
+ this.gs_location = gs_location;
+ }
+
+ public String getCus_number() {
+ return cus_number;
+ }
+
+ public void setCus_number(String cus_number) {
+ this.cus_number = cus_number;
+ }
+
+ public String getCus_expires() {
+ return cus_expires;
+ }
+
+ public void setCus_expires(String cus_expires) {
+ this.cus_expires = cus_expires;
+ }
+
+ public String getCus_master() {
+ return cus_master;
+ }
+
+ public void setCus_master(String cus_master) {
+ this.cus_master = cus_master;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+}
diff --git a/src/main/resources/conf.properties b/src/main/resources/conf.properties
new file mode 100644
index 0000000..02c42e7
--- /dev/null
+++ b/src/main/resources/conf.properties
@@ -0,0 +1,16 @@
+#\u5355\u70B9\u767B\u5F55\u7EDF\u4E00\u5730\u5740
+auth_url=https://www.singlewindow.shaanxi.cn/oauth/authorize
+#\u83B7\u53D6tokan\u5730\u5740
+token_url=https://www.singlewindow.shaanxi.cn/oauth/token
+#\u83B7\u53D6\u7528\u6237\u4FE1\u606F\u63A5\u53E3
+user_url=https://www.singlewindow.shaanxi.cn/resource/user
+#client_id
+client_id=125d5ff7-a40a-11eb-8e31-005056826ea5
+#client_secret
+client_secret=93badcc315cf94843040c2d9f254094f6eb71e0f
+#\u767B\u51FA\u540E\u8DF3\u8F6C\u5730\u5740
+logout=https://www.singlewindow.shaanxi.cn/oauth/logout
+##\u56DE\u8C03\u5730\u5740
+redirect_uri=http://locahost:8075/webroot/decision
+##\u586B\u62A5\u5730\u5740
+write_report=
\ No newline at end of file
diff --git a/交付教程.docx b/交付教程.docx
new file mode 100644
index 0000000..120a633
Binary files /dev/null and b/交付教程.docx differ