SSO、单点登录、集成 Apereo CAS

JeeSite 已经默认集成了两种单点登录方式(Single Sign On):

1、SSO(简单登录)接口,实现快速登录系统。

2、与 Apereo CAS 服务器集成,快速实现系统登录(个人版)

简单登录接口

系统登录:

1、设置 application.yml(v4.0.x:jeesite.yml)的 shiro.sso.secretKey 快速登录安全Key,若不设置将无法使用该接口。

  1. shiro:
  2. # 简单 SSO 登录相关配置
  3. sso:
  4. # 如果启用/sso/{username}/{token}单点登录,请修改此安全key并与单点登录系统key一致。
  5. secretKey: thinkgem
  6. # 是否加密单点登录安全Key
  7. encryptKey: true

2、举例调用地址如下,调用完成后自动登录系统:

  1. http://localhost/project/sso/{username}/{token}?url=/sys/user/list?p1=v1%26p2=v2&relogin=true
  • username: 登录名,数据库中的 login_code 字段。
  • token: 登录令牌,根据yml里配置的登录安全Key生产的密码。
  • url: 登录之后要跳转的地址,如果url中携带参数,请使用转义字符,如“&”号,使用“%26”转义。 token生成方式:
  1. String username = "system"; // 登录系统名
  2. String secretKey = "thinkgem"; // yml 中设置的 shiro.sso.secretKey 参数值。
  3. String token = Md5Utils.md5(secretKey + username + DateUtils.getDate("yyyyMMdd"));
  4. // 如果 shiro.sso.encryptKey 为 true,则 secretKey 会自动加密。
  5. // 如果在本系统获取,则 secretKey 已经加密了,也可以通过下面这个简便方法获取。
  6. String token = UserUtils.getSsoToken(username);

该接口源码如下(提供参考):

  1. /**
  2. * 单点登录(如已经登录,则直接跳转)
  3. * @param username 登录用户名(loginCode)
  4. * @param token 单点登录令牌,令牌组成:sso密钥+用户名+日期,进行md5加密,举例:
  5. * // 注意如果 shiro.sso.encryptKey 为 true,则 secretKey 会自动加密。
  6. * String secretKey = Global.getConfig("shiro.sso.secretKey");
  7. * String token = Md5Utils.md5(secretKey + username + DateUtils.getDate("yyyyMMdd"));
  8. * @param params 登录附加参数(JSON格式),或 param_ 前缀的请求参数。
  9. * @param url 登录成功后跳转的url地址。
  10. * @param relogin 是否强制重新登录,需要强制重新登录传递true
  11. */
  12. @RequestMapping(value = "sso/{username}/{token}")
  13. public String sso(@PathVariable String username, @PathVariable String token,
  14. @RequestParam(defaultValue="${adminPath}") String url, String relogin,
  15. HttpServletRequest request, Model model){
  16. User user = UserUtils.getUser();
  17. // 如果已经登录,并且是同一个人,并且不强制重新登录,则直接跳转到目标页
  18. if(StringUtils.isNotBlank(user.getUserCode())
  19. && StringUtils.equals(user.getLoginCode(), username)
  20. && !ObjectUtils.toBoolean(relogin)){
  21. return REDIRECT + EncodeUtils.decodeUrl2(url);
  22. }
  23. // 通过令牌登录系统
  24. if (token != null){
  25. try {
  26. FormToken upToken = new FormToken();
  27. upToken.setUsername(username); // 登录用户名
  28. upToken.setSsoToken(token); // 单点登录令牌
  29. upToken.setParams(ServletUtils.getExtParams(request)); // 登录附加参数
  30. UserUtils.getSubject().login(upToken);
  31. return REDIRECT + EncodeUtils.decodeUrl2(url);
  32. } catch (AuthenticationException e) {
  33. if (!e.getMessage().startsWith("msg:")){
  34. throw new AuthenticationException("msg:登录失败,请联系管理员。", e);
  35. }
  36. throw e;
  37. }
  38. }
  39. return "error/403";
  40. }

无条件登录举例:

  1. String username = "admin";
  2. FormToken upToken = new FormToken();
  3. upToken.setUsername(username);
  4. upToken.setSsoToken(UserUtils.getSsoToken(username));
  5. UserUtils.getSubject().login(upToken);
  6. String sid = UserUtils.getSession().getId().toString();
  7. System.out.println(sid);

系统退出:

  1. http://127.0.0.1:8980/js/a/logout

注意:无 cookie 环境下,必须要指定要退出的 sessionid

集成 Apereo CAS

CAS 客户端配置非常简单,开启如下配置,设置好服务于客户端跳转地址即可:

  1. shiro:
  2. #索引页路径
  3. defaultPath: ${shiro.loginUrl}
  4. # Apereo CAS 相关配置(个人版)
  5. casServerUrl: http://127.0.0.1:8981/cas
  6. casClientUrl: http://127.0.0.1:8980/js
  7. loginUrl: ${shiro.casServerUrl}?service=${shiro.casClientUrl}${adminPath}/login-cas
  8. logoutUrl: ${shiro.casServerUrl}/logout?service=${shiro.loginUrl}
  9. successUrl: ${shiro.casClientUrl}${adminPath}/index

注意此功能是个人版功能,只有个人版以上版本才能使用。