`

编写你自己的单点登录二(SSO)服务(转)

阅读更多
6 桌面 SSO 的实现
WEB-SSO 的概念延伸开,我们可以把 SSO 的技术拓展到整个桌面的应用,不仅仅局限在浏览器。 SSO 的概念和原则都没有改变,只需要再做一点点的工作,就可以完成桌面 SSO 的应用。
桌面 SSO WEB-SSO 一样,关键的技术也在于如何在用户登录过后保存登录的凭据。在 WEB-SSO 中,登录的凭据是靠浏览器的 cookie 机制来完成的;在桌面应用中,可以将登录的凭证保存到任何地方,只要所有 SSO 的桌面应用都共享这个凭证。
从网站可以下载一个简单的桌面 SSO 的样例 (http://gceclub.sun.com.cn/wangyu/desktop-sso/desktopsso.zip) 和全部源码( http://gceclub.sun.com.cn/wangyu/desktop-sso/desktopsso_src.zip ),虽然简单,但是它具有桌面 SSO 大多数的功能,稍微加以扩充就可以成为自己的解决方案。
 
6.1 桌面样例的部署
  1. 运行此桌面 SSO 需要三个前提条件:
    a) WEB-SSO
    的身份认证应用应该正在运行,因为我们在桌面 SSO 当中需要用到统一的认证服务
    b)
    当前桌面需要运行 Mozilla Netscape 浏览器,因为我们将 ticket 保存到 mozilla cookie 文件中
    c)
    必须在 JDK1.4 以上运行。( WEB-SSO 需要 JDK1.5 以上)
  2. 解开 desktopsso.zip 文件,里面有两个目录 bin lib
  3. bin 目录下有一些脚本文件和配置文件,其中 config.properties 包含了三个需要配置的参数:
    a) SSOServiceURL
    要指向 WebSSO 部署的身份认证的 URL
    b) SSOLoginPage
    要指向 WebSSO 部署的身份认证的登录页面 URL
    c) cookiefilepath
    要指向当前用户的 mozilla 所存放 cookie 的文件
  4. bin 目录下还有一个 login.conf 是用来配置 JAAS 登录模块,本样例提供了两个,读者可以任意选择其中一个(也可以都选),再重新运行程序,查看登录认证的变化
  5. bin 下的运行脚本可能需要作相应的修改
    a)
    如果是在 unix 下,各个 jar 文件需要用“ : 来隔开,而不是“ ;
    b) java
    运行程序需要放置在当前运行的路径下,否则需要加上 java 的路径全名。
 
6.2 桌面样例的运行
样例程序包含三个简单的 Java 控制台程序,这三个程序单独运行都需要登录。如果运行第一个命叫“ GameSystem 的程序,提示需要输入用户名和密码:
效验成功以后,便会显示当前登录的用户的基本信息等等。
 这时候再运行第二个桌面 Java 应用( mailSystem )的时候,就不需要再登录了,直接就显示出来刚才登录的用户。
第三个应用是 logout ,运行它之后,用户便退出系统。再访问的时候,又需要重新登录了。请读者再制裁执行完 logout 之后,重新验证一下前两个应用的 SSO :先运行第二个应用,再运行第一个,会看到相同的效果。
我们的样例并没有在这里停步,事实上,本样例不仅能够和在几个 Java 应用之间 SSO ,还能和浏览器进行 SSO ,也就是将浏览器也当成是桌面的一部分。这对一些行业有着不小的吸引力。
这时候再打开 Mozilla 浏览器,访问以前提到的那两个 WEB 应用,会发现只要桌面应用如果登录过, Web 应用就不用再登录了,而且能显示刚才登录的用户的信息。读者可以在几个桌面和 Web 应用之间进行登录和 logout 的试验,看看它们之间的 SSO
6.3 桌面样例的源码分析
桌面 SSO 的样例使用了 JAAS (要了解 JAAS 的详细的信息请参考 http://java.sun.com/products/jaas )。 JAAS 是对 PAM Pluggable Authentication Module )的 Java 实现,来完成 Java 应用可插拔的安全认证模块。使用 JAAS 作为 Java 应用的安全认证模块有很多好处,最主要的是不需要修改源代码就可以更换认证方式。例如原有的 Java 应用如果使用 JAAS 的认证,如果需要应用 SSO ,只需要修改 JAAS 的配置文件就行了。现在在流行的 J2EE 和其他 Java 的产品中,用户的身份认证都是通过 JAAS 来完成的。在样例中,我们就展示了这个功能。请看配置文件 login.conf
    DesktopSSO {
   desktopsso.share.PasswordLoginModule required;
   desktopsso.share.DesktopSSOLoginModule required;
};
当我们注解掉第二个模块的时候,只有第一个模块起作用。在这个模块的作用下,只有 test 用户(密码是 12345 )才能登录。当我们注解掉第一个模块的时候,只有第二个模块起作用,桌面 SSO 才会起作用。
 
所有的 Java 桌面样例程序都是标准 JAAS 应用,熟悉 JAAS 的程序员会很快了解。 JAAS 中主要的是登录模块( LoginModule )。下面是 SSO 登录模块的源码:
  public class DesktopSSOLoginModule implements LoginModule {
   ..........
   private String SSOServiceURL = "";
   private String SSOLoginPage = "";
   private static String cookiefilepath = "";  
   .........
 
config.properties 的文件中,我们配置了它们的值:
SSOServiceURL=http://wangyu.prc.sun.com:8080/SSOAuth/SSOAuth
SSOLoginPage=http://wangyu.prc.sun.com:8080/SSOAuth/login.jsp
cookiefilepath=C:\\Documents and Settings\\yw137672\\Application Data\\Mozilla\\Profiles\\default\\hog6z1ji.slt\\cookies.txt
SSOServiceURL SSOLoginPage 成员变量指向了在 Web-SSO 中用过的身份认证模块: SSOAuth ,这就说明在桌面系统中我们试图和 Web 应用共用一个认证服务。而 cookiefilepath 成员变量则泄露了一个“天机”:我们使用了 Mozilla 浏览器的 cookie 文件来保存登录的凭证。换句话说,和 Mozilla 共用了一个保存登录凭证的机制。之所以用 Mozilla 是应为它的 Cookie 文件格式简单,很容易编程访问和修改任意的 Cookie 值。(我试图解析 Internet Explorer cookie 文件但没有成功。)
下面是登录模块DesktopSSOLoginModule的主体: login() 方法。逻辑也是非常简单:先用 Cookie 来登陆,如果成功,则直接就进入系统,否则需要用户输入用户名和密码来登录系统。
    public boolean login() throws LoginException{
        try {
            if (Cookielogin()) return true;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
      if (passwordlogin()) return true;
      throw new FailedLoginException();
  }
 
下面是Cookielogin() 方法的实体,它的逻辑是: 先从 Cookie 文件中获得相应的 Cookie 值,通过身份效验服务效验 Cookie 的有效性。如果 cookie 有效 就算登录成功;如果不成功或 Cookie 不存在,用 cookie 登录就算失败。
    public boolean Cookielogin() throws LoginException,IOException {
      String cookieValue="";
      int cookieIndex =foundCookie();
      if (cookieIndex<0)
            return false;
      else
            cookieValue = getCookieValue(cookieIndex);
     username = cookieAuth(cookieValue);
     if (! username.equals("failed")) {
         loginSuccess = true;
         return true;
     }
     return false;
  }
 
 
用用户名和密码登录的方法要复杂一些,通过 Callback 的机制和屏幕输入输出进行信息交互,完成用户登录信息的获取;获取信息以后通过 userAuth 方法来调用远端 SSOAuth 的服务来判定当前登录的有效性。
   public boolean passwordlogin() throws LoginException {
    //
    // Since we need input from a user, we need a callback handler
    if (callbackHandler == null) {
       throw new LoginException("No CallbackHandler defined");
    }
    Callback[] callbacks = new Callback[2];
    callbacks[0] = new NameCallback("Username");
    callbacks[1] = new PasswordCallback("Password", false);
    //
    // Call the callback handler to get the username and password
    try {
      callbackHandler.handle(callbacks);
      username = ((NameCallback)callbacks[0]).getName();
      char[] temp = ((PasswordCallback)callbacks[1]).getPassword();
      password = new char[temp.length];
      System.arraycopy(temp, 0, password, 0, temp.length);
      ((PasswordCallback)callbacks[1]).clearPassword();
    } catch (IOException ioe) {
      throw new LoginException(ioe.toString());
    } catch (UnsupportedCallbackException uce) {
      throw new LoginException(uce.toString());
    }
   
    System.out.println();
    String authresult ="";
    try {
        authresult = userAuth(username, password);
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    if (! authresult.equals("failed")) {
        loginSuccess= true;
        clearPassword();
        try {
            updateCookie(authresult);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return true;
    }
  
 
    loginSuccess = false;
    username = null;
    clearPassword();
    System.out.println( "Login: PasswordLoginModule FAIL" );
    throw new FailedLoginException();
  }
 
 
CookieAuth userAuth 方法都是利用 apahce httpclient 工具包和远程的 SSOAuth 进行 http 连接,获取服务。
        private String cookieAuth(String cookievalue) throws IOException{
        String result = "failed";
       
        HttpClient httpclient = new HttpClient();      
        GetMethod httpget = new GetMethod(SSOServiceURL+Action1+cookievalue);
   
        try {
            httpclient.executeMethod(httpget);
            result = httpget.getResponseBodyAsString();
        } finally {
            httpget.releaseConnection();
        }
        return result;
    }
 
private String userAuth(String username, char[] password) throws IOException{
        String result = "failed";
        String passwd= new String(password);
        HttpClient httpclient = new HttpClient();      
        GetMethod httpget = new GetMethod(SSOServiceURL+Action2+username+"&password="+passwd);
        passwd = null;
   
        try {
            httpclient.executeMethod(httpget);
            result = httpget.getResponseBodyAsString();
        } finally {
            httpget.releaseConnection();
        }
        return result;
       
    }
 
还有一个地方需要补充说明的是,在本样例中,用户名和密码的输入都会在屏幕上显示明文。如果希望用掩码形式来显示密码,以提高安全性,请参考: http://java.sun.com/developer/technicalArticles/Security/pwordmask/
7 真正安全的全方位 SSO 解决方案: Kerberos
我们的样例程序(桌面 SSO WEB-SSO )都有一个共性:要想将一个应用集成到我们的 SSO 解决方案中,或多或少的需要修改应用程序。 Web 应用需要配置一个我们预制的 filter ;桌面应用需要加上我们桌面 SSO JAAS 模块(至少要修改 JAAS 的配置文件)。可是有很多程序是没有源代码和无法修改的,例如常用的远程通讯程序 telnet ftp 等等一些操作系统自己带的常用的应用程序。这些程序是很难修改加入到我们的 SSO 的解决方案中。
事实上有一种全方位的 SSO 解决方案能够解决这些问题,这就是 Kerberos 协议( RFC 1510 )。 Kerberos 是网络安全应用标准 (http://web.mit.edu/kerberos/ ) ,由 MIT 学校发明,被主流的操作系统所采用。在采用 kerberos 的平台中,登录和认证是由操作系统本身来维护,认证的凭证也由操作系统来保存,这样整个桌面都可以处于同一个 SSO 的系统保护中。操作系统中的各个应用(如 ftp,telnet )只需要通过配置就能加入到 SSO 中。另外使用 Kerberos 最大的好处在于它的安全性。通过密钥算法的保证和密钥中心的建立,可以做到用户的密码根本不需要在网络中传输,而传输的信息也会十分的安全。
目前支持 Kerberos 的操作系统包括 Solaris, windows,Linux 等等主流的平台。只不过要搭建一个 Kerberos 的环境比较复杂, KDC (密钥分发中心)的建立也需要相当的步骤。 Kerberos 拥有非常成熟的 API ,包括 Java API 。使用 Java Generic Security Services(GSS) API 并且使用 JAAS 中对 Kerberos 的支持(详细信息请参见 Sun Java&Kerberos 教程 http://java.sun.com/ j2se/1.5.0/docs/guide/security/jgss/tutorials/index.html ),要将我们这个样例改造成对 Kerberos 的支持也是不难的。 值得一提的是在 JDK6.0 http://www.java.net/download/jdk6 )当中直接就包含了对 GSS 的支持,不需要单独下载 GSS 的包。
 
8 总结
本文的主要目的是阐述 SSO 的基本原理,并提供了一种实现的方式。通过对源代码的分析来掌握开发 SSO 服务的技术要点和充分理解 SSO 的应用范围。但是,本文仅仅说明了身份认证的服务,而另外一个和身份认证密不可分的服务 ---- 权限效验,却没有提到。要开发出真正的 SSO 的产品,在功能上、性能上和安全上都必须有更加完备的考虑。
作者简介
王昱是 Sun 中国工程研究院的 Java 工程师,现在的主要负责全球合作伙伴的技术支持。作为一名 Java 资深工程师和架构师,王昱在 Java 的很多领域都有多年的造诣,特别是在 Java 虚拟机、 J2EE 技术 ( 包括 EJB, JSP/Servlet, JMS Web services 等技术 ) 、集群技术和 Java 应用性能调优上有着较为丰富的经验。曾经多次在重要的 Java 会议发表演讲,并在国际著名的 Java 技术站 点发表文章。
 
资源链接
分享到:
评论

相关推荐

    编写自己的单点登录(SSO)服务

    单点登录 SSO单点登录 SSO单点登录 SSO单点登录 SSO

    编写你自己的单点登录(SSO)服务

    单点登录(Single Sign-On,简称SSO)是一种在多应用环境中实现用户只需一次登录就能访问所有相互信任应用系统的身份认证技术。它旨在提高用户体验,减少管理负担,并增强安全性。SSO通过统一的身份验证中心来处理...

    编写你自己的单点登录(SSO)服务

    单点登录(Single Sign-On,简称SSO)是一种网络身份验证技术,允许用户在一个系统中登录后,无需再次输入凭证即可访问其他相互信任的系统。这种技术在企业环境中尤其重要,因为它提高了用户体验,减少了安全管理的...

    SSO单点登录DEMO

    SSO(Single Sign-On)单点登录是一种网络身份验证机制,允许用户在多个相互关联的应用系统之间进行无缝的登录切换,而无需重复输入认证信息。SSO的核心思想是让用户只需要一次登录,就能访问所有受保护的资源,提高...

    跨服务器登录验证(单点登录SSO)过程和Java实现

    总结来说,单点登录(SSO)通过集中式的身份验证服务,为多应用环境提供了便捷的用户登录体验。在Java环境下,借助Spring Security这样的框架,我们可以轻松地构建起自己的SSO系统,为用户提供无缝的跨系统访问。在...

    C#单点登录示例程序SSO

    单点登录(Single Sign-On,简称SSO)是一种网络用户身份验证的机制,允许用户在一次登录后,就可以访问多个相互关联的应用系统,而无需再次进行身份验证。在这个C#实现的SSO示例程序中,我们将探讨如何构建这样一个...

    sso单点登录demo.zip

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户在一次登录后访问多个应用程序,而无需再次输入凭证。在这个"ssso单点登录demo.zip"压缩包中,包含了一个基于Spring Boot、Spring Data JPA和MySQL实现的...

    C#单点登陆组件源码SSO

    单点登录(Single Sign-On,简称SSO)是一种网络身份验证机制,允许用户在一个系统上登录后,无需再次验证即可访问多个相互关联的系统。在IT行业中,SSO技术广泛应用于企业级应用,提高用户体验,简化管理并增强安全...

    编写你自己的单点登录服务

    ### 编写你自己的单点登录服务 #### 单点登录概述 单点登录(Single Sign-On,简称SSO)是一种认证模式,它允许用户在多个应用系统中仅需完成一次登录过程,即可访问所有相互信任的应用系统。这种模式不仅提高了...

    ssm redis实现sso单点登录

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证。在本文中,我们将深入探讨如何使用SSM(Spring MVC、Spring、MyBatis)框架结合Redis...

    SSO单点登录实例

    SSO(Single Sign-On)单点登录是一种网络应用中用户身份验证的技术,允许用户通过一次登录操作访问多个相互信任的应用系统。在这个实例中,我们将会深入理解SSO的工作原理,并通过提供的项目Demo来实践这一技术。 ...

    Jeecg配置单点登录 登录验证完整代码

    在本场景中,我们关注的是Jeecg如何配置单点登录(Single Sign-On,简称SSO)以及相关的登录验证代码。单点登录是一种网络应用架构中的安全机制,允许用户在一次登录后,就能访问多个相互关联的应用系统,而无需再次...

    sso单点登录服务端程序

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户通过一次登录操作访问多个相互关联的应用系统,而无需多次输入凭证。这种技术在现代企业信息化建设中扮演着重要角色,因为它提高了用户体验,同时也简化...

    SSO CAS单点登录配置教程

    SSO(Single Sign-On)是单点登录的缩写,是一种网络访问控制方式,它允许用户使用一组凭证(如用户名和密码)登录一次,然后在多个应用系统间自由切换而无需再次验证身份。CAS(Central Authentication Service)是...

    SSO(单点登录) 技术的实现

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证。这一技术在现代企业信息化建设中扮演着重要角色,因为它提供了便捷的用户体验,同时...

    sso单点登录代码.zip

    SSO(Single Sign-On)单点登录是一种身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次进行身份验证。在IT领域,尤其是企业级应用开发中,SSO是提高用户体验和安全性的重要技术。Spring ...

    单点登录(SingleSignOn-SSO)完整案例

    单点登录(Single Sign-On,简称SSO)是一种身份验证机制,允许用户在一次登录后访问多个相互关联的应用系统,而无需再次输入凭证。这种技术极大地提升了用户体验,减少了登录过程中的繁琐步骤,同时也能增强安全性...

Global site tag (gtag.js) - Google Analytics