JAAS是一个可插入框架,例如它的登陆模块可以随意更改,而不用去修改你现有的代码,你只需在配置文件中指定登陆模块,还有就是权限策略,你可以用一个文件来配置用户的权限,你也可以实现自己的ProtectDomain类,来读取XML文件,现在JAAS还不是一个完全成熟的产品,所有各位不要期望它可以适应于任何系统,但是java技术的成熟也肯定会让JAAS技术成熟起来的

解决方案 »

  1.   

    上面的叙述有点小错误,即用一统一的Servlet把客户端代码封装起来
    public class MyServlet extends HttpServlet {
      public void doPost(HttpServletRequest req,HttpServletResponse resp) throws LoginException {
       String username =req.getParameter("username");
       String password =req.getParameter("password");
       LoginContext lc = new LoginContext("xxxx",new CallbackHandler(username,password);
       lc.login();
      }
    }
      

  2.   


    JAAS认证需要用到如下几个类或者接口。
    1. LoginModule 
    该接口主要实现用户的验证。它包括如下几种认证方式。
    (1) KerberosLoginModule
    (2) NtLoginMoudle
    该类主要包括如下几个方法
       A  Initialize()  
    B  Login()
       C  Commit()
       D  Abort()
     E  Logout()
    2.Callback回调处理程序。
       该接口主要实现与用户的交互。
        主要包括一下几种接口
        A  TextOutCallbackHandler
        B  NameCallback   获取用户名称
        C  PasswordCallback  获取用户密码
        D  ChoiceCallbackr
        E  ConfirmCallbackr
       主要方法是Handle();
    2. Subject 对象
    主要有如下几个方法
    ●subject.getPrincipals() 返回一组 Principal 对象。因为结果是 Set,所以适用操作 remove()、add() 和 contains()。
    • subject.getPublicCredentials() 返回一组与 Subject 相关的公用可访问凭证。
    • subject.getPrivateCredentials() 返回一组与 Subject 相关的专用可访问凭证。 
    3.Principal 接口
     Principal 是一个 Java 接口。程序员编写的 PrincipalImpl 对象与 Serializable 接口、名称字符串、返回该字符串的 getName() 方法以及其它支持方法(如 hashCode()、toString() 和 equals())一起实现 Principal 接口。在登录过程期间,Principal 被添加到 Subject。
    4 登陆配置
    JAAS 使用 login.config 文件来指定每个登录模块的认证项。login.config 文件是在 Java 执行命令行上用特性 -Djava.security.auth.login.config==login.config 指定的。Java 有缺省登录配置文件,所以双等于号(==)替换系统登录配置文件。如果使用一个等于号,login.config 文件将被添加到(而不是替换)系统登录配置文件 
    login.config 文件包含 LoginContext 构造器中引用的文本字符串和登录过程列表。几个参数用于指定一个给定的登录过程的成功或失败对总体认证过程的影响。有如下参数:
    • required 表示登录模块必须成功。即使它不成功,还将调用其它登录模块。
    • optional 表示登录模块可以失败,但如果另一个登录模块成功,总体登录仍可以成功。如果所有登录模块都是可选的,那么要使整个认证成功至少必须有一个模块是成功的。
    • requisite 表示登录模块必须成功,而且如果它失败,将不调用其它登录模块。
    • sufficient 表示如果登录模块成功,则总体登录将成功,同时假设没有其它必需或必不可少的登录模块失败。 §
    login.config 文件示例:
        JAASExample {
          AlwaysLoginModule required;
          PasswordLoginModule optional;
    };
    5 LoginContext类
    LoginContext 是一种用于设置登录过程的 Java 类,它进行实际的登录,如果登录成功,获取 Subject。它主要有如下几种方法。
    •  LoginContext("JAASExample", newUsernamePasswoerdCallbackHandler()) 是构造器。它把 login.config 文件中使用的字符串作为其第一个参数,把执行实际任务的回调处理程序作为其第二个参数。(接下来,我们将讨论回调处理程序。)
    • login(),它根据 login.config 文件中指定的规则实际尝试登录。
    • getSubject(),如果登录总体成功,它返回经认证的 Subject。
    • logout(),它向 LoginContext 注销 Subject
    综上,为了实现JAAS在项目中的应用,我们可以修改LoginModule中的Login()方法以及Callback的Handle()方法,以适应项目的需要。将用户名和密码和数据库中的用户名和密码做比较来实现用户的认证。
    二 JAAS 授权
    将包含在访问控制环境中的权限特征与策略文件中的 Java 权限 grant 语句进行比较,以表明是否允许敏感操作。这是由名为 AccessController 的 Java 实用程序完成的,它的接口用于通过程序检查特权以及将当前的 Subject 与活动的访问控制环境相关联。
          我们可以使用doAs(Subject sub,PrivilegedAction action)将具有特殊权限才能访问的代码与Subject联系起来。也可以使用doAs(Subject sub,PrivilegedAction action,AccessController acc).我们可以将PrivilegedAction里面的类的Run方法修改,加入需要保护的代码,就可以实现相应的授权机制。这种方法属于程序性授权。比如如下程序。
    Public 0class PayrollAction  implements PrivilegedAction {
         public Object run() {
           // Get the passed in subject from the DoAs
           AccessControlContext context = AccessController.getContext();
           Subject subject = Subject.getSubject(context );
           if (subject == null ) {
             throw new AccessControlException("Denied");
           }
           //
           // Iterate through the principal set looking for joeuser.  If
           // he is not found,
           Set principals = subject.getPrincipals();
           Iterator iterator = principals.iterator();
           while (iterator.hasNext()) {
             PrincipalImpl principal = (PrincipalImpl)iterator.next();
             if (principal.getName().equals( "joeuser" )) {
               System.out.println("joeuser has Payroll access\n");
               return new Integer(0);
             }
           }
           throw new AccessControlException("Denied");
    }
    还有一种声明性授权方式,使用方法如下:
    import java.io.*;
    import java.security.*;
    //
    // This class is a sensitive Personnel function that demonstrates 
    // the use of declarative authorization using the user defined 
    // permission PersonnelPermission, which throws an exception 
    // if it not granted 
    class PersonnelAction implements PrivilegedAction {
         public Object run() {
           AccessController.checkPermission(new PersonnelPermission("access"));
           System.out.println( "Subject has Personnel access\n");
           return new Integer(0);
         }
    }
    策略文件的格式比如:
    grant {
         permission javax.security.auth.AuthPermission "createLoginContext";
         permission javax.security.auth.AuthPermission "doAs";
         permission javax.security.auth.AuthPermission "doAsPrivileged";
         permission javax.security.auth.AuthPermission "modifyPrincipals";
         permission javax.security.auth.AuthPermission "getSubject"; };grant      principal PrincipalImpl "Brad" {
         permission PersonnelPermission "access";
    };
      

  3.   

    我现在一个在想如何用JAAS实现EJB内方法的保护,楼上的同志可不可以一起进行探讨呢?我的
    e-mail:[email protected]
      

  4.   

    zyymmm(今宵酒醒何处,杨柳岸,晓风残月) 兄弟,你是否明白Permission实现的工作原理?
      

  5.   

    zyymmm(今宵酒醒何处,杨柳岸,晓风残月) 兄弟,你是否曾经使用Authenticator和JAAS联合使用呢,我总觉得现在的办法虽然是解决了JAAS如何整合到WEB环境中,到我始终觉得这不是最好的办法,我感觉如果把Authenticator和JAAS联合使用,将能达到更好的效果
      

  6.   

    超级好~~最近我也在用JAAS,希望能和你取得联系
      

  7.   

    to chendequan(陈德全) :
      
        我对JAAS的了解非常粗浅,目前JAVA方面的工作,精力主要集中在GUI设计和XML方面,阁下提到的EJB结合JAAS进行方法保护在<精通EJB>(第二版)第九章有介绍和相关例子.    阁下就SERVLET与JAAS结合方面进行的阐述对我启发很大,希望以后继续发表类似好贴,JAVA版的朋友都会支持你的.  :)
      

  8.   

    我已经看了这本书籍了,但里面的实现方法是通过在EJB里配置ejb-jar.xml来实现的,我现在的商业应用程序已经完成了,现在我做的是安全应用,要求不改变已有商业应用,能不能给些建议,我有一套思路,但是好象实现起来比较困难,就是自己根据授权机制,再开发出来一套授权系统,
    比如定制
    EJBMethodPermission
    XMLPolicyFile
    MyAccessControlContext
    MyPriviledgedAction
    但是我现在觉得很难实现的就是EJBMethodPermission这个类,就是你怎么知道EJB有这个方法,并且如何去把这个方法保护起来