`
thinkgem
  • 浏览: 585943 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

简单实现Shiro单点登录(自定义Token令牌)

阅读更多

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);
		}
	}
 
}

 

 

分享到:
评论
3 楼 qq124410675 2015-12-03  
我当前网页没有登录,但是访问子系统的这个方法就直接能登录……

help
2 楼 qq124410675 2015-12-03  
请问一下这代码对吗?是怎么验证客户机登录状态的?   我用了这段代码,直接访问sso这个方法就自动登录…  help
1 楼 softkuba 2015-07-21  
请问如何将其他应用绑定到此系统,进而通过会话访问实现单点登录呢

相关推荐

    springboot+redis+shiro单点登录,统一异常处理,统一日志

    总结起来,这个项目将SpringBoot的便捷性与Shiro的安全控制和Redis的高速缓存相结合,实现了高效的SSO单点登录,同时提供了统一的异常处理和日志管理机制,提高了系统的稳定性和用户体验。这是一套完整的解决方案,...

    SpringBoot 整合 Shiro 实现动态权限加载更新+Session 共享+单点登录.docx

    在本文中,我们将深入探讨如何在SpringBoot项目中整合Apache Shiro框架,实现动态权限加载更新、Session共享以及单点登录功能。Shiro是一个轻量级的安全管理框架,虽然其功能相比Spring Security略显简单,但对许多...

    java实现可跨浏览器单点登录

    单点登录(Single Sign On,简称SSO)是一种身份验证机制,允许用户在一次登录后,无需再次输入凭证即可访问多个相互信任的应用系统。在Java环境下实现SSO,可以为企业的信息化管理提供便利,减少用户的登录操作,...

    sso与shiro整合所需工具类

    SSO(Single Sign-On)是单点登录的缩写,它允许用户在多个应用程序中进行身份验证,只需要登录一次即可。Apache Shiro是一款强大的安全管理框架,用于处理认证、授权、会话管理和加密等任务。本教程将探讨如何将SSO...

    跟我学shiro

    #### 十五、单点登录 - **概念**:用户只需一次登录就可以访问所有相关系统。 - **实现**: - **服务器端**:实现 SSO 的核心逻辑。 - **客户端**:与服务器端交互,完成 SSO 过程。 #### 十六、综合实例 - **...

    Shiro教程.pdf

    - **服务器端**:实现单点登录的逻辑。 - **客户端**:处理单点登录后的重定向。 #### 十六、综合实例 - **案例演示**:结合前面学习的知识点,构建一个完整的示例项目。 #### 十七、OAuth2集成 - **服务器端**:...

    shiro用户教程pdf

    这包括了如何配置Shiro、实现登录认证、实现权限控制等。 ### 第十七章:OAuth2集成 #### 17.1 服务器端 OAuth2是一种开放标准授权协议,用于实现授权流程。Shiro可以与OAuth2结合使用,实现在服务器端的认证和...

    shiro教程共享

    Shiro还支持单点登录(SSO)的实现,允许多个应用共享一个登录凭证。综合实例的章节提供了Shiro在实际项目中的应用案例。 在身份验证方面,REMEMBER ME功能允许用户在不同的会话中保持登录状态。SSL章节讲解了如何...

    SSO单点登录解决方案

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次输入凭证。这种技术在现代企业级应用中广泛应用,简化了用户操作,提高了用户体验,同时也降低了...

    shiro-oauth2开源代码

    Shiro集成OAuth2时,可能需要实现一个授权服务器端点,用于处理用户的授权请求,生成访问令牌(Access Token)和刷新令牌(Refresh Token)。 4. **客户端配置**: 在Shiro中,需要配置OAuth2客户端信息,如...

    SpringAll_wuyouzhuguli.tar.gz

    Spring Security OAuth2单点登录 四、Spring Cloud教程 初识Spring Cloud与微服务 Spring Cloud Eureka服务治理 Spring Cloud Ribbon客户端负载均衡 Spring Cloud Hystrix服务容错 Spring Cloud Hystrix Dashboard...

    java bbs 整合

    论坛的简称)进行集成,实现单点登录(Single Sign-On, SSO)和统一的退出功能。单点登录允许用户在一个系统登录后,无需再次认证就能访问其他关联系统,提供更好的用户体验。 首先,我们要理解SSO的工作原理。在...

    Java单点登录系统 JA-SIG CAS源码

    Java单点登录(Single Sign-On, SSO)系统是一种允许用户通过一次登录验证即可访问多个应用系统的身份认证机制。JA-SIG CAS(Central Authentication Service)是开源社区开发的一个基于Java的SSO解决方案,广泛应用...

    cas 进阶篇一

    4. **单点登出**:理解如何实现用户在一次登出后,同时退出所有已认证的应用。 5. **自定义认证**:通过源码解析,学习如何编写自己的认证模块以支持不同的凭证类型,如LDAP、数据库或其他外部系统。 6. **票证...

Global site tag (gtag.js) - Google Analytics