前言–项目需求
在智慧校园系统中,加入一个超链接,直接跳转到XX系统。
思路
前提:本系统同步了单点登录服务器中的账户信息
点击超链接时,访问XX系统接口,由xx系统接口去访问sos服务器,取得当前登录账户的信息,
若与xx系统同步的信息匹配,则由sos服务器回调成功url。
(中间涉及在sos服务器配置xx系统信息和回调成功地址信息等)
1.导包
pom文件依赖:
<!--CAS Client-->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.4.1</version>
</dependency>
<!--CAS Client Autoconfig-Support-->
<!-- https://mvnrepository.com/artifact/net.unicon.cas/cas-client-autoconfig-support -->
<dependency>
<groupId>net.unicon.cas</groupId>
<artifactId>cas-client-autoconfig-support</artifactId>
<version>2.3.0-GA</version>
</dependency>
2.配置
application.properties 文件配置
#cas配置
#cas服务端前缀
cas.server-url-prefix=http://authserver.swun.edu.cn/authserver
#cas的登录地址
cas.server-login-url=http://authserver.swun.edu.cn/authserver/login
#当前客户端的地址(替换 me.local 为域名或ip地址 ip或域名需要在cas server授权)
cas.client-host-url=http://me.local/meeting-web/casClient/loginByCasClient
#cas.client-host-url=http://172.18.0.246/meeting-web/casClient/loginByCasClient
cas.validation-type=CAS3
#设置拦截url地址
cas.authentication-url-patterns[0]=/casClient/loginByCasClient
cas.validation-url-patterns[0]=/casClient/loginByCasClient
cas.request-wrapper-url-patterns[0]=/casClient/loginByCasClient
cas.assertion-thread-local-url-patterns[0]=/casClient/loginByCasClient
3.编写逻辑完成登录
退出同理,xx系统采用jwt,逻辑类比。
/**
* 1. 人员组织已通过定时任务同步 2. cas已登录 1.1 重定向
*
* @param request
* @param response
* @return
* @throws IOException
*/
@AuthIgnore
@ApiOperation("登录 - loginByCasClient")
@GetMapping(value = "/loginByCasClient")
public String loginByCasClient(HttpServletRequest request, HttpServletResponse response, HttpSession sessions)
throws IOException {
String cas_token = (String) sessions.getAttribute("cas_token");
if ( !"".equals(cas_token)&&null!=cas_token) {
logger.info("直接登录!");
return "<!--\n"
+ " @author : biuaxia\n"
+ " @date: 2020/1/15 10:42\n"
+ " @apiNote: contact biuaxia@qq.com,\n"
+ "-->\n"
+ "<!DOCTYPE html>\n"
+ "<html lang=\"en\">\n"
+ "<head>\n"
+ " <meta charset=\"utf-8\"/>\n"
+ " <title>引导页</title>\n"
+ " <title>恭喜,站点创建成功!</title>\n"
+ " <style>\n"
+ " .container {\n"
+ " width: 60%;\n"
+ " margin: 10% auto 0;\n"
+ " background-color: #f0f0f0;\n"
+ " padding: 2% 5%;\n"
+ " border-radius: 10px;\n"
+ " }\n"
+ "\n"
+ " ul {\n"
+ " padding-left: 20px;\n"
+ " }\n"
+ "\n"
+ " ul li {\n"
+ " line-height: 2.3;\n"
+ " }\n"
+ "\n"
+ " a {\n"
+ " color: #20a53a;\n"
+ " }\n"
+ " </style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<div class=\"container\">\n"
+ " <h1>恭喜, 登录成功!</h1>\n"
+ " <h3>3秒后为您跳转到会议系统页面,请耐心等待</h3>\n"
+ " <ul>\n"
+ " <li>本页面由系统自动生成</li>\n"
+ " <li>您可以忽略本页面,直接访问会议系统/meeting-web</li>\n"
+ " <li>直接登录</li>\n"
+ " </ul>\n"
+ "</div>\n"
+ "\n"
+ "<script>\n"
+ " localStorage.setItem(\"token\", \""
+ cas_token
+ "\");\n"
+ " setTimeout(function () {\n"
+ " window.location.href = '/meeting-web/#/personalSet'\n"
+ " }, 3000);\n"
+ "</script>\n"
+ "</body>\n"
+ "</html>";
}
String loginName = request.getRemoteUser();
String userName;
if (loginName == null || "".equals(loginName)) {
logger.info("未登录、重定向到默认登录页面");
response.sendRedirect(context_path);
} else {
Principal principal = request.getUserPrincipal();
AttributePrincipal aPrincipal = (AttributePrincipal) principal;
Map<String, Object> map = aPrincipal.getAttributes();
userName = (String) map.get("cn");
logger.info(
String.format("login By CasClient -- loginName: %s, userName: %s", loginName, userName));
}
BaseUserinfo existUserInfo = baseUserinfoService.getByLoginName(loginName);
if (existUserInfo == null) {
throw new RequestParamException(String.format("用户 %s 不存在.", loginName));
}
if (existUserInfo.getUserStatus().intValue() == 0) {
throw new RequestParamException("用户被禁用");
}
UserInfo userInfo = new UserInfo();
userInfo.setId(existUserInfo.getId());
userInfo.setLoginName(existUserInfo.getLoginName());
userInfo.setUserName(existUserInfo.getUserName());
userInfo.setDeptId(existUserInfo.getOrgId());
cas_token = tokenService.generateToken(userInfo);
sessions.setAttribute("cas_token", cas_token);
logger.info("正常登录!");
// TODO biuaxia 可以在登录时检查session,若存在直接登录,反之跳转cas,在退出时移除session的内容(仅供参考, 2020年1月15日14:33:53)
return "<!--\n"
+ " @author : biuaxia\n"
+ " @date: 2020/1/15 10:42\n"
+ " @apiNote: contact biuaxia@qq.com,\n"
+ "-->\n"
+ "<!DOCTYPE html>\n"
+ "<html lang=\"en\">\n"
+ "<head>\n"
+ " <meta charset=\"utf-8\"/>\n"
+ " <title>引导页</title>\n"
+ " <title>恭喜,站点创建成功!</title>\n"
+ " <style>\n"
+ " .container {\n"
+ " width: 60%;\n"
+ " margin: 10% auto 0;\n"
+ " background-color: #f0f0f0;\n"
+ " padding: 2% 5%;\n"
+ " border-radius: 10px;\n"
+ " }\n"
+ "\n"
+ " ul {\n"
+ " padding-left: 20px;\n"
+ " }\n"
+ "\n"
+ " ul li {\n"
+ " line-height: 2.3;\n"
+ " }\n"
+ "\n"
+ " a {\n"
+ " color: #20a53a;\n"
+ " }\n"
+ " </style>\n"
+ "</head>\n"
+ "<body>\n"
+ "<div class=\"container\">\n"
+ " <h1>恭喜, 登录成功!</h1>\n"
+ " <h3>3秒后为您跳转到会议系统页面,请耐心等待</h3>\n"
+ " <ul>\n"
+ " <li>本页面由系统自动生成</li>\n"
+ " <li>您可以忽略本页面,直接访问会议系统/meeting-web</li>\n"
+ " <li>正常登录</li>\n"
+ " </ul>\n"
+ "</div>\n"
+ "\n"
+ "<script>\n"
+ " localStorage.setItem(\"token\", \""
+ cas_token
+ "\");\n"
+ " setTimeout(function () {\n"
+ " window.location.href = '/meeting-web/#/personalSet'\n"
+ " }, 3000);\n"
+ "</script>\n"
+ "</body>\n"
+ "</html>";
}
退出
@AuthIgnore
@ApiOperation("退出-logoutByCasClient")
@PostMapping("/logoutCasClient")
public void logoutByCas(HttpServletRequest request) throws ServletException {
tokenService.logout(request.getHeader("token"));
request.getSession().invalidate();
request.logout();
logger.info("logout By CasClient Success!");
}
注:退出只退出了xx系统,应考虑做单点退出。