`

java实现简单的单点登录(4)

阅读更多

下面是登录模块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();
 }
 
 CookieAuthuserAuth方法都是利用apahcehttpclient工具包和远程的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/
 
当前方案的安全局限性
当前这个WEB-SSO的方案是一个比较简单的雏形,主要是用来演示SSO的概念和说明SSO技术的实现方式。有很多方面还需要完善,其中安全性是非常重要的一个方面。
我们说过,采用SSO技术的主要目的之一就是加强安全性,降低安全风险。因为采用了SSO,在网络上传递密码的次数减少,风险降低是显然的,但是当前的方案却有其他的安全风险。由于cookie是一个用户登录的唯一凭据,对cookie的保护措施是系统安全的重要环节:
  • cookie的长度和复杂度
    在本方案中,cookie是有一个固定的字符串(我的姓名)加上当前的时间戳。这样的cookie很容易被伪造和猜测。怀有恶意的用户如果猜测到合法的cookie就可以被当作已经登录的用户,任意访问权限范围内的资源
  • cookie的效验和保护
    在本方案中,虽然密码只要传输一次就够了,可cookie在网络中是经常传来传去。一些网络探测工具(如sniff, snoop,tcpdump等)可以很容易捕获到cookie的数值。在本方案中,并没有考虑cookie在传输时候的保护。另外对cookie的效验也过于简单,并不去检查发送cookie的来源究竟是不是cookie最初的拥有者,也就是说无法区分正常的用户和仿造cookie的用户。
  • 当其中一个应用的安全性不好,其他所有的应用都会受到安全威胁
    因为有SSO,所以当某个处于 SSO的应用被黒客攻破,那么很容易攻破其他处于同一个SSO保护的应用。
这些安全漏洞在商业的SSO解决方案中都会有所考虑,提供相关的安全措施和保护手段,例如Sun公司的Access Managercookie的复杂读和对cookie的保护都做得非常好。另外在OpneSSO https://opensso.dev.java.net)的架构指南中也给出了部分安全措施的解决方案。
当前方案的功能和性能局限性
除了安全性,当前方案在功能和性能上都需要很多的改进:
  • 当前所提供的登录认证模式只有一种:用户名和密码,而且为了简单,将用户名和密码放在内存当中。事实上,用户身份信息的来源应该是多种多样的,可以是来自数据库中,LDAP中,甚至于来自操作系统自身的用户列表。还有很多其他的认证模式都是商务应用不可缺少的,因此SSO的解决方案应该包括各种认证的模式,包括数字证书,Radius, SafeWord MemberShipSecurID等多种方式。最为灵活的方式应该允许可插入的JAAS框架来扩展身份认证的接口
  • 我们编写的Filter只能用于J2EE的应用,而对于大量非JavaWeb应用,却无法提供SSO服务。
  • 在将Filter应用到Web应用的时候,需要对容器上的每一个应用都要做相应的修改,重新部署。而更加流行的做法是Agent机制:为每一个应用服务器安装一个agent,就可以将SSO功能应用到这个应用服务器中的所有应用。
  • 当前的方案不能支持分别位于不同domainWeb应用进行SSO。这是因为浏览器在访问Web服务器的时候,仅仅会带上和当前web服务器具有相同domain名称的那些cookie。要提供跨域的SSO的解决方案有很多其他的方法,在这里就不多说了。SunAccess Manager就具有跨域的SSO的功能。
  • 另外,Filter的性能问题也是需要重视的方面。因为Filter会截获每一个符合URL映射规则的请求,获得cookie,验证其有效性。这一系列任务是比较消耗资源的,特别是验证cookie有效性是一个远程的http的调用,来访问SSOAuth的认证服务,有一定的延时。因此在性能上需要做进一步的提高。例如在本样例中,如果将URL映射从“.jsp改成“/*,也就是说filter对所有的请求都起作用,整个应用会变得非常慢。这是因为,页面当中包含了各种静态元素如gif图片,css样式文件,和其他html静态页面,这些页面的访问都要通过filter去验证。而事实上,这些静态元素没有什么安全上的需求,应该在filter中进行判断,不去效验这些请求,性能会好很多。另外,如果在filter中加上一定的cache,而不需要每一个cookie效验请求都去远端的身份认证服务中执行,性能也能大幅度提高。
  • 另外系统还需要很多其他的服务,如在内存中定时删除无用的cookie映射等等,都是一个严肃的解决方案需要考虑的问题。
桌面SSO的实现
WEB-SSO的概念延伸开,我们可以把SSO的技术拓展到整个桌面的应用,不仅仅局限在浏览器。SSO的概念和原则都没有改变,只需要再做一点点的工作,就可以完成桌面 SSO 的应用。
桌面SSOWEB-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) 
    当前桌面需要运行MozillaNetscape浏览器,因为我们将ticket保存到mozillacookie文件中
    c) 
    必须在JDK1.4以上运行。(WEB-SSO需要JDK1.5以上)
  2. 解开desktopsso.zip文件,里面有两个目录binlib
  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是对PAMPluggable 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 
 SSOServiceURLSSOLoginPage成员变量指向了在Web-SSO中用过的身份认证模块:SSOAuth,这就说明在桌面系统中我们试图和Web应用共用一个认证服务。而cookiefilepath成员变量则泄露了一个“天机”:我们使用了Mozilla浏览器的cookie文件来保存登录的凭证。换句话说,和Mozilla共用了一个保存登录凭证的机制。之所以用Mozilla是应为它的Cookie文件格式简单,很容易编程访问和修改任意的Cookie值。(我试图解析Internet Explorercookie文件但没有成功。)
分享到:
评论

相关推荐

    JAVA单点登录的实现

    1,通过session会话来判断 2,实现单点登录

    JAVA实现单点登录功能

    JAVA 实现单点登录功能 ! 包含 所有的详细文档 ! 试用手册值得学习

    最新java实现简单的单点登录

    在提供的压缩包"最新java实现简单的单点登录.doc"中,可能包含了关于如何使用Java Web和Spring Security实现SSO的具体步骤、配置代码示例和常见问题解答等内容。读者可以通过阅读这份文档,进一步了解和学习如何在...

    基于Java集成CAS单点登录【接部署即可启用】

    基于Java中CAS的单点登录,有服务端的所有源码,将tomcat目录下的所有资源直接拷到Tomcat服务中间件的webapp目录下,阅读tomcat-webapp中的read.txt文档,查看使用说明,适用于第一次开发CAS单点登录的同学们,简单...

    java实现简单的单点登录

    间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式...

    用Java实现单点登录

    单点登录(Single Sign-...以上就是Java实现单点登录的一些关键知识点,每个方面都需要深入了解和恰当配置,以构建一个安全、高效的SSO系统。实际开发过程中,还需要结合业务场景,考虑性能、扩展性和用户体验等因素。

    java跨域单点登录实现

    Java跨域单点登录(Single Sign-On,SSO)实现是一项关键的系统集成技术,它允许用户在多个应用系统中只需登录一次,就能访问所有相互信任的应用系统,无需再次进行身份验证。本项目代码着重展示了如何在Java环境中...

    java实现单点登录_图例及相关代码

    Java 实现单点登录技术详解 单点登录(SSO)是一种流行的企业业务整合解决方案,它允许用户在多个应用系统中只需要登录一次就可以访问所有相互信任的应用系统。SSO 技术的出现是为了解决企业内部多个业务系统之间的...

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

    跨服务器登录验证(单点登录SSO)的过程和Java实现 跨服务器登录验证(单点登录SSO)是指用户只需要登录一次便可以访问多个相关的应用系统的机制。这种机制可以提高用户体验和系统安全性。下面我们将介绍跨服务器...

    微博Oauth2.0 协议用java 实现单点登录获取用户信息

    在Java中实现微博的单点登录(Single Sign-On, SSO)功能,涉及到的主要步骤包括注册应用、获取授权码、交换访问令牌、获取用户信息等。下面我们将详细探讨这些过程。 1. **注册应用**: 在开始实现之前,你需要在...

    java单点登录流程及其他

    在 Java 中实现单点登录需要使用到 Jwt(JSON Web Tokens),Jwt 是一种基于 Token 的身份验证机制,可以与 SSO 一起使用,但并不是 SSO 的必要组成部分。 首先,我们需要配置 SecurityConfig 类,该类是 Spring ...

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

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

    shiro+spring+data+session+redis实现单点登录

    本案例聚焦于使用Apache Shiro、Spring、Spring Data以及Redis来实现单点登录功能,下面将详细解释这些组件以及它们如何协同工作。 **Apache Shiro** Apache Shiro是一款轻量级的安全框架,提供了认证、授权、会话...

    java应用系统单点登录

    它通过共享Session和Cookie来实现单点登录。在Shiro中,可以通过配置Realm(域)来对接不同的认证源,如数据库、LDAP、CAS等。 4. **JWT(JSON Web Token)**: JWT是一种开放标准,用于在网络应用之间安全地传输...

    "java实现简单的单点登录"源码包

    http://www.blogjava.net/xcp/archive/2010/04/13/318125.html 页面的源码地址无法访问,我在其他地方找到了。可以运行的三个简单应用,配置完成后可以实现单点登录,供初学者研究其原理。

    spring+springMvc简单实现SSO单点登录

    利用springMvc 实现的简单的单点登录Demo,内含三个小Mavn项目分别是 1、认证中心SSOServer 2、子系统1SSOClient1 3、子系统2SSOClient2 文章请参考 http://blog.csdn.net/qq_31183297/article/details/79419222

    Java实现基于KeyCloak的单点登录权限管理POC验证源码.zip

    Java实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC验证源码.zipJava实现基于KeyCloak的单点登录权限管理POC...

    java-cas单点登录服务端

    CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,本文介绍了 CAS 的原理、协议、在 Tomcat 中的配置和使用,研究如何采用 CAS 实现轻量级单点登录解决方案。 CAS 是 Yale 大学发起的...

    rtx单点登录(JAVA实现)

    jsp实现RXT单点登录,单点登录要求在OA服务器安装Server SDK开发包,同时需要配置RTX服务器安装目录下的AppConnConfig.xml文件,把OA服务器的IP地址加进来,例如OA服务器地址为172.30.21.20,配置如下所示: ...

    CAS单点登录(java)

    CAS单点登录CAS单点登录CAS单点登录CAS单点登录

Global site tag (gtag.js) - Google Analytics