结合JAAS实现J2EE的安全认证和授权

来源:互联网 发布:调查问卷怎么分析数据 编辑:程序博客网 时间:2024/05/16 10:50
java web的认证和授权
1. J2EE 资源保护的声明式安全
容器管理的安全将所有访问控制决策委托给 J2EE 容器,从而将应用程序逻辑与安全定义进行明确的划分。容器管理的安全中的用户角色在 Web 应用程序部署描述符 (web.xml) 中进行定义,静态地映射到在目标 J2EE 容器中定义的安全角色。声明式 J2EE 安全通过 Web 应用程序的 URL 模式对其进行保护,这些模式可以是完整的绝对路径或相对路径和文件扩展名。例如,要仅向作为 USERS 角色成员的用户授予对某个应用程序的访问权限,web.xml 文件中需要以下定义:
  <security-constraint>
    <display-name>RemoteControl service security policy</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <url-pattern>/otas.do</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>otas</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <display-name>SIMTrace service security policy</display-name>
    <web-resource-collection>
      <web-resource-name>Protected Area</web-resource-name>
      <url-pattern>/address.do</url-pattern>
      <http-method>DELETE</http-method>
      <http-method>GET</http-method>
      <http-method>POST</http-method>
      <http-method>PUT</http-method>
    </web-resource-collection>
    <auth-constraint>
      <role-name>address</role-name>
    </auth-constraint>
  </security-constraint>
2. 角色映射
对于执行编程授权以保持与 web.xml 文件中或目标平台上定义的角色之间相互独立的 J2EE Web 应用程序代码,J2EE 允许应用程序开发人员在其应用程序代码中定义逻辑角色名,而后映射到 web.xml 部署描述符文件中的角色名。 
例如,在应用程序代码中(可以在 Struts 操作、JavaServer Faces (JSF) 管理的 Bean 或 JavaServer Page (JSP) 页面中),应用程序开发人员将使用 request.isUserInRole("Otas") 验证是否已授予用户访问特定资源或信息的权限。在给出的示例中,通过将 <security-role-ref> 元素用作 web.xml 部署描述符文件中 <servlet></servlet> 元素的子元素,可以将应用程序代码中使用的 VALID_USER 角色名映射到 web.xml 文件中定义的 USERS 角色。
  <security-role>
    <role-name>otas</role-name>
  </security-role>
  <security-role>
    <role-name>address</role-name>
  </security-role>
3. 用户认证和授权
当用户请求一个受保护的 Web 应用程序区域时,强制执行声明式安全中的认证。如果用户之前没有经过认证,则为该用户显示一个登录对话框来标识自身。常用的认证类型包括基于
 FORM 的认证和 BASIC 认证。
BASIC 认证使用浏览器登录对话框供用户输入其用户名和口令。该对话框形式不能自定义,因此其外观取决于使用的浏览器类型。用户证书存储在经过认证的区域的浏览器会话中。J2EE 中的区域是一个保护域,为经过认证的用户定义了一组权限。使用 Basic 认证时,每个请求中的用户名和口令都在 HTTP 头部中以 base64 编码形式发送。
基于 FORMS 的认证允许应用程序开发人员指定自定义登录对话框。必须将用户名参数命名为 j_username,将口令域命名为 j_password。登录表单动作必须将值 j_security_check 用于 J2EE 容器以对请求进行认证。用户在整个服务器会话中始终是经过认证的。但再实际项目中,我们并不想将用户名参数命名为 j_username,将口令域命名为 j_password,登录表单动作值命名为 j_security_check .因此我们需要定制org.apache.catalina.startup.Authenticators.properties的配置为
BASIC=org.apache.catalina.authenticator.BasicAuthenticator
CLIENT-CERT=org.apache.catalina.authenticator.SSLAuthenticator
DIGEST=org.apache.catalina.authenticator.DigestAuthenticator
FORM=org.apache.catalina.authenticator.FormAuthenticator
NONE=org.apache.catalina.authenticator.NonLoginAuthenticator
FORM_EXT=com.ceno.ota.security.authenticator.FormAuthenticator
其中com.ceno.ota.security.authenticator.FormAuthenticator需要做改动,具体参照附件。
认证类型在 web.xml 部署描述符文件中用 <login-config> 元素指定。
  <login-config>
    <auth-method>FORM_EXT</auth-method>
    <realm-name>Tomcat Manager Application</realm-name>
    <form-login-config>
      <form-login-page>/login.do</form-login-page>
      <form-error-page>/no_permission.do</form-error-page>
    </form-login-config>
  </login-config>
4. jaas认证方式
tomcat容器本身提供类似MemoryRealm,JDBCRealm和JAASRealm的各种认证方式,而Java 认证和授权服务 (JAAS) 包含一组 API 和接口,可进行细粒度的编程认证和授权。JAAS 主要用于扩展 Java 2 Security 平台,不但能够基于代码位置执行授权,还能够根据执行代码的用户进行授权。JAAS 中的认证通过一个可插入的认证模块体系结构 (PAM) 进行,该体系结构使用一个或多个 LoginModule 对用户或服务进行认证。与声明式 J2EE 安全相比,JAAS 允许安全开发人员针对单个应用程序自定义认证过程。更改应用程序的认证源代码时,无需更改 J2EE 应用程序代码。
      <Realm className="com.ceno.ota.security.realm.JAASRealm"
             throwFaultException="true"
             noPermissionPage="/app1/login.do"
             forward="false"
             context="false"
             appName="auth" useContextClassLoader="false"
             userClassNames="com.ceno.ota.security.principal.UserPrincipal"
             roleClassNames="com.ceno.ota.security.principal.RolePrincipal"
             debug="99"
          /> 
JAAS 认证的关键是可插入的 LoginModule,这些模块根据回调处理程序提供的信息执行认证。自定义的 LoginModule 必须实施由 javax.security.auth.spi.LoginModule 接口定义的方法。JAASRealm在认证的过程中将调用loginModule来进行认证和授权。
回调处理程序用于获取用户证书以传递至 LoginModule(一个或多个)进行认证。用户证书可通过登录对话框、令牌、证书以及开发人员能想到的任何方式提供。LoginModule 的 login() 方法由 LoginContext 调用进行用户认证,成功认证时返回 true,认证失败时返回 false,或在出现故障时引发 javax.security.auth.login.LoginException。LoginContext 的责任是读取 LoginModule 配置文件并调用为特定应用程序配置的每个 LoginModule。 
登录模块类名后的标志指示在多个 LoginModule 配置情况下,认证过程在成功或失败时如何继续。使用多个 LoginModule,应用程序安全管理员可以对应用程序执行分级认证,即根据添加到 Subject 的经过认证的 Principle 的类型和数量,不同的用户具有不同的权限。可用的标志选择如下所示:
Required LoginModule 必须成功。认证始终继续,直至 LoginModule 列表的末尾,但如果其中一个必需的 LoginModule 对用户进行认证失败,整个认证将失败。 
Requisite LoginModule 必须成功。如果成功,认将继续直至 LoginModule 列表末尾。如果失败,控制立即返回至应用程序。 
Sufficient  LoginModule 无需成功。如果成功,控制立即返回至应用程序。如果失败,认证继续直至 LoginModule 列表末尾。 Optional  LoginModule 无需成功。成功认证后,LoginModule 将实例 java.security.Principal 添加到 Subject,Subject中存放User相关信息和role的相关信息。JaasRealm调用整个LoginModule成功后,将返回Subject,并对其进行处理,存放在session会话中。 
jaas.conf配置如下:
auth {
    com.ceno.ota.security.auth.AuthenticationLoginModule required debug=true names=test001;
    com.ceno.ota.security.auth.AuthorizationLoginModule required debug=true test001=otas;
};
 
demo依赖commons-beanutils.jar,commons-digester.jar,javaee.jar,struts.jar,将附件中的lib拷贝至tomcat根目录下,附件中conf下的文件copy并覆盖到tomcat/conf下,并将web下的app1和app2拷贝至tomcat/webapps下既可以运行。
 
附件地址 : http://heaven-demo.googlecode.com/files/security.zip