1. MVC Controller 映射 sso 方法。
/** * 单点登录(如已经登录,则直接跳转) * @param userCode 登录用户编码 * @param token 登录令牌,令牌组成:sso密钥+用户名+日期,进行md5加密,举例: * String secretKey = Global.getConfig("shiro.sso.secretKey"); * String token = Digests.md5(secretKey + userCode + DateUtils.getDate("yyyyMMdd")); * @param url 登录成功后跳转的url地址。 * @param relogin 是否重新登录,需要重新登录传递true * 例如:http://localhost/project/sso/{token}?url=xxx&relogin=true */ @RequestMapping(value = "sso/{userCode}/{token}") public String sso(@PathVariable String userCode, @PathVariable String token, @RequestParam(required=true) String url, String relogin, Model model) { Principal principal = UserUtils.getPrincipal(); // 如果已经登录 if(principal != null){ // 如果设置强制重新登录,则重新登录 if (BooleanUtils.toBoolean(relogin)){ UserUtils.getSubject().logout(); } // 否则,直接跳转到目标页 else{ return "redirect:" + Encodes.urlDecode2(url); } } // 进行单点登录 if (token != null){ UsernamePasswordToken upt = new UsernamePasswordToken(); try { upt.setUsername(userCode); // 登录用户名 upt.setPassword(token.toCharArray()); // 密码组成:sso密钥+用户名+日期,进行md5加密,举例: Digests.md5(secretKey+username+20150101)) upt.setParams(upt.toString()); // 单点登录识别参数,see: AuthorizingRealm.assertCredentialsMatch } catch (Exception ex){ if (!ex.getMessage().startsWith("msg:")){ ex = new AuthenticationException("msg:授权令牌错误,请联系管理员。"); } model.addAttribute("exception", ex); } try { UserUtils.getSubject().login(upt); return "redirect:" + Encodes.urlDecode2(url); } catch (AuthenticationException ae) { if (!ae.getMessage().startsWith("msg:")){ ae = new AuthenticationException("msg:授权错误,请检查用户配置,若不能解决,请联系管理员。"); } model.addAttribute("exception", ae); } } return "error/403"; }
2. 重载org.apache.shiro.realm.AuthorizingRealm类的assertCredentialsMatch方法
/** * 认证密码匹配调用方法 */ @Override protected void assertCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; // 若单点登录,则使用单点登录授权方法。 if (token.toString().equals(token.getParams())){ // sso密钥+用户名+日期,进行md5加密,举例: Digests.md5(secretKey+username+20150101)) String secretKey = Global.getConfig("shiro.sso.secretKey"); String password = Digests.md5(secretKey + token.getUsername() + DateUtils.getDate("yyyyMMdd")); if (password.equals(String.valueOf(token.getPassword()))){ return; } } super.assertCredentialsMatch(token, info); }
3. 实现Shiro无状态访问,如通过传递sessionid参数即可实现会话访问
这里需要自定义Shiro的SessionManager类,方法是继承org.apache.shiro.web.session.mgt.DefaultWebSessionManager类,重载getSessionId方法,如下:
public class SessionManager extends DefaultWebSessionManager { public SessionManager() { super(); } @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { // 如果参数中包含“__sid”参数,则使用此sid会话。 例如:http://localhost/project?__sid=xxx&__cookie=true // 其实这里还可以使用如下参数:cookie中的session名称:如:JSESSIONID=xxx,路径中的 ;JESSIONID=xxx,但建议还是使用 __sid参数。 String sid = request.getParameter("__sid"); if (StringUtils.isNotBlank(sid)) { // 是否将sid保存到cookie,浏览器模式下使用此参数。 if (WebUtils.isTrue(request, "__cookie")){ HttpServletRequest rq = (HttpServletRequest)request; HttpServletResponse rs = (HttpServletResponse)response; Cookie template = getSessionIdCookie(); Cookie cookie = new SimpleCookie(template); cookie.setValue(sid); cookie.saveTo(rq, rs); } // 设置当前session状态 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.URL_SESSION_ID_SOURCE); // session来源与url request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sid); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return sid; }else{ return super.getSessionId(request, response); } } }
相关推荐
Springboot+shiro单点登录实现,本文档是单点登录的全部源代码。
spring整合shirospring-data-redis和spring-session-data-redis通过shiro实现单点登录
shiro+spring+data+session+redis实现单点登录,这是一个不错的案例,学习和参考都是很不错的
cas 结合 springmvc shiro 做项目单点登录包括cas服务端,cas客户端。shiro-cas集成项目
本文档详细介绍了shiro的单点登录的实现原理,以及如何一步一步的搭建单点登录环境。
springboot+redis+shiro单点登录,统一异常处理,统一日志,缓存
springboot整和jwt、shiro、redis实现token自动刷新
shiro 单点登录 shiro 单点登录
shiro+cas实现单点登录 示例代码,送源码分析url:http://note.youdao.com/noteshare?id=a83380ee8fc6913162042e865689844e&sub=CD905CCCE4134A159326DC2DFC1AF268
SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 SpringBoot整合Shiro示例实现动态权限加载更新+Session共享+单点登录 ...
spring下使用shiro+cas配置单点登录,多个系统之间的访问,每次只需要登录一次
Shiro安全框架, 实现系统的单点登陆和登出功能, 包含数据库文件
基于 SpringBoot + Spring + SpringMvc + Mybatis + Shiro+ Redis 开发单点登录管理系统 基于 SpringBoot + Spring + SpringMvc + Mybatis + Shiro+ Redis 开发单点登录管理系统 基于 SpringBoot + Spring + ...
分析shiro框架+cas单点登录系统的技术分析,解析了相关的技术难点
SpringBoot整合Shiro、JWT和Redis实现token登录授权验证以及token刷新 前端代码为一个博客页面,使用了Semantic UI框架结合thymeleaf模板 SpringBoot结合JWT+Shiro+Redis实现token无状态登录授权 [TOC] 一、引言 ...
spring下使用shiro+cas配置单点登录,多个系统之间的访问,每次只需要登录一次 ## 系统模块说明 1. cas: 单点登录模块,这里直接拿的是cas的项目改了点样式而已 2. doc: 文档目录,里面有数据库生成语句,采用的...
shiro-demo不自定义缓存,
cas+ springmvc + shiro实现单点登录
spring boot 1.5.4 集成shiro+cas,实现单点登录和权限控制.docx,这是一份CAS单点登录的技术文档