`

SSO单点登录学习(一)

    博客分类:
  • sso
阅读更多
我对于一个新的内容学习.一般先知道其作用和特点是什么.然后从网上看下有什么例子和说明最后自己做几个符合自己需求的例子。

SSO:单点登录.一般是系统之间整合需要解决的一个问题.例如你之前做了个BBS或者一个CMS的系统.你在完成一个全新系统时候需要用到BBS这个系统的话..你就可能面临一个整合的问题.(除非你自己决定从新做个BBS上去) 对于我们已有的WEB应用中的用户,若该用户已经登陆,并通过 联结迁移到BBS页面时,BBS要能够识别该用户已经登陆(不需要二次登陆)才不会让用户感到别扭(对用户来说,就好像使用的是同一个系统似的)。

下面看下Jforum对于SSO的处理.
首先找到SSO处理所有类:net.jforum.sso下的SSO(需要实现的接口) SSOUtils(工具类)类;net.jforum.ControllerUtils;net.jforum.JForum
首先从xml中可以看到net.jforum.JForum这是整个系统一个核心的servlet.所以所有访问将通过该实体类
1.当一个用户访问JForum时.刷新session
ControllerUtils utils = new ControllerUtils();
// 刷新session
utils.refreshSession();

2.进入ControllerUtils的refreshSession()
public void refreshSession()
	{
		UserSession userSession = SessionFacade.getUserSession();//获取系统用户session
		RequestContext request = JForumExecutionContext.getRequest();//获取封装后的request值

		if (userSession == null) {//如果userSession不存在话
			userSession = new UserSession();
			userSession.registerBasicInfo();//初始化基础信息
			userSession.setSessionId(request.getSessionContext().getId());
			userSession.setIp(request.getRemoteAddr());
			SessionFacade.makeUnlogged();//清除登录session的值

			if (!JForumExecutionContext.getForumContext().isBot()) {//如果不是机器登录
				// Non-SSO authentications can use auto login
				/**
				 * 要启用sso功能话需要配置SystemGlobals.properties的中
				 * authentication.type的值=ConfigKeys.TYPE_SSO
				 */
				if (!ConfigKeys.TYPE_SSO.equals(SystemGlobals.getValue(ConfigKeys.AUTHENTICATION_TYPE))) {
					if (SystemGlobals.getBoolValue(ConfigKeys.AUTO_LOGIN_ENABLED)) {
						this.checkAutoLogin(userSession);
					}
					else {
						userSession.makeAnonymous();
					}
				}
				else {
					this.checkSSO(userSession);//检测sso
				}
			}

			SessionFacade.add(userSession);//将userSession设置到SessionFacade
		}
		else if (ConfigKeys.TYPE_SSO.equals(SystemGlobals.getValue(ConfigKeys.AUTHENTICATION_TYPE))) {//是否启用sso
			SSO sso;
			
			try {
				/**
				 * ConfigKeys.SSO_IMPLEMENTATION 
				 * 取决你用什么方式实现SSO 可以是Cookies形式或者JDAP等形式而相应完成的实现类需要在SystemGlobals.properties配置 sso.implementation = 实现类完整路径
				 */
				sso = (SSO) Class.forName(SystemGlobals.getValue(ConfigKeys.SSO_IMPLEMENTATION)).newInstance();
			}
			catch (Exception e) {
				throw new ForumException(e);
			}

			// If SSO, then check if the session is valid
			if (!sso.isSessionValid(userSession, request)) {//session值是否通过SSO验证.
				SessionFacade.remove(userSession.getSessionId());
				refreshSession();
			}
		}
		else {
			SessionFacade.getUserSession().updateSessionTime();
		}
	}

从代码中可以看出.checkSSO这个方法将是重点:
protected void checkSSO(UserSession userSession)
	{
		try {
			/**
			 * ConfigKeys.SSO_IMPLEMENTATION 
			 * 中对应SystemGlobals.properties配置中SSO的实现类
			 * 取决你用什么方式实现SSO 
			 * 可以是Cookies形式或者JDAP等形式 sso.implementation = 实现类完整路径
			 */
			SSO sso = (SSO) Class.forName(SystemGlobals.getValue(ConfigKeys.SSO_IMPLEMENTATION)).newInstance();
			/**
			 * sso检测用户.返回为用户的值
			 */
			String username = sso.authenticateUser(JForumExecutionContext.getRequest());
			/**
			 * 若返回了一个null,则设置为“Anonymous” (设置匿名用户)
			 * checkAutoLogin()将调用makeAnonymous()里面设置的匿名cookies值
			 * 若一个“Anonymous”用户试图访问权限以外的页面,
			 * JForum将根据SSO的设置导航到登陆页面,
			 * 同时传递给一个登陆成功后应该迁移到的地址参数给login页面。
			 */
			if (username == null || username.trim().equals("")) {
				userSession.makeAnonymous();
			}
			/**
			 *  若返回了一个不为空的username时,
			 * JForum将会检查是否匹配JForum数据库的userid。
			 *  若没有匹配的userid,JForum将动态加以创建
			 * 
			 */
			else {
				SSOUtils utils = new SSOUtils();

				if (!utils.userExists(username)) {//如果用户不存在进行添加
					SessionContext session = JForumExecutionContext.getRequest().getSessionContext();

					String email = (String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_EMAIL_ATTRIBUTE));
					String password = (String) session.getAttribute(SystemGlobals.getValue(ConfigKeys.SSO_PASSWORD_ATTRIBUTE));

					if (email == null) {
						email = SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_EMAIL);
					}

					if (password == null) {
						password = SystemGlobals.getValue(ConfigKeys.SSO_DEFAULT_PASSWORD);
					}

					utils.register(password, email);//JForum设置该user为登陆状态 
				}

				this.configureUserSession(userSession, utils.getUser());
			}
		}
		catch (Exception e) {
			e.printStackTrace();
			throw new ForumException("Error while executing SSO actions: " + e);
		}
	}

上面只是小弟的一些理解.希望高手可以提点下..
SSO这个接口提供了2个方法 对于自己的需求进行相应SSO技术选择
技术选择有可以看下:http://blog.163.com/anly_liu/blog/static/42832314200810212619493/
下面可能整理一下做个符合自己的例子出来(使用cookies来实现)
分享到:
评论
1 楼 幽默大润哥 2012-06-07  
这东西挺有意思

相关推荐

Global site tag (gtag.js) - Google Analytics