使用WebSphere Application Server社区版配置EJB应用程序安全性

保护企业Java Bean(EJB)是Java EE应用程序安全性的最重要方面之一。 IBM WebSphere Application Server社区版V2.1(以下称为社区版)是基于Apache Geronimo v2.1的免费使用的Java Enterprise Edition 5.0(Java EE5)认证的应用程序服务器,用于保护EJB应用程序。 Community Edition使用Apache OpenEJB作为其EJB容器。 通过在部署描述符中定义安全角色来配置EJB身份验证和授权,每种方法都将在该描述符中执行。 然后,您将安全角色映射到Community Edition特定的部署计划中的主体。

在本文中,我们讨论了使用Community Edition保护会话,实体和消息驱动的EJB可用的不同选项。 我们还开发了一些EJB应用程序来演示各种安全配置。 要继续学习,您需要WebSphere Application Server Community Edition v2.1。

一个没有安全性的简单EJB应用程序

让我们检查一个没有配置安全性的简单EJB应用程序。 该应用程序包含一个EJB2.1无状态会话Bean和一个EJB3无状态会话Bean。 清单1显示了该应用程序的部署描述符ejb-jar.xml

清单1:显示bean定义的部署描述符
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar ...>
    <display-name>SimpleEjbApp</display-name>
    <enterprise-beans>
        <session>
            <description>Simple Session Bean</description>
            <display-name>SimpleSessionBean</display-name>
            <ejb-name>SimpleSessionBean</ejb-name>
            <home>simple.ejb21.SimpleServiceHome</home>
            <remote>simple.ejb21.SimpleService</remote>
            <local-home>simple.ejb21.SimpleServiceLocalHome</local-home>
            <local>simple.ejb21.SimpleServiceLocal</local>
            <ejb-class>simple.ejb21.SimpleServiceBean</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Container</transaction-type>
        </session>
    </enterprise-beans>
</ejb-jar>

注意,部署描述符仅显示一个bean定义,即SimpleSessionBean。 我们使用bean类中的注释指定EJB3会话bean的部署元数据。 清单2显示了Simple3ServiceBean的bean类。

清单2:Simple3ServiceBean类
import  javax.ejb.Stateless;
...

@Stateless
public class Simple3ServiceBean implements Simple3Service {

	  public String commonMethod(){
		  ...
	  }

	  public String userMethod(){
		  ...
	  }

	  public String adminMethod(){
		  ...
	  }
	  
	  public String noaccessMethod(){
		  ...
	  }
}

在此示例中,@Stateless批注指定Simple3ServiceBean是无状态会话Bean。

会话bean SimpleSessionBeanSimple3ServiceBean都没有配置任何安全性,因此所有方法都具有不受限制的访问权限。 清单3显示了此应用程序的部署计划openejb-jar.xml

清单3:简单的EJB应用程序部署计划
<openejb-jar ...>
    <environment>
        <moduleId>
            <groupId>dw</groupId>
            <artifactId>simple-ejb-app</artifactId>
            <version>1.0</version>
            <type>jar</type>
        </moduleId>
        <dependencies/>
        <hidden-classes/>
        <non-overridable-classes/>
    </environment>
    <enterprise-beans>
        <session>
            <ejb-name>SimpleSessionBean</ejb-name>
            <jndi-name>ejb/SimpleSessionBean</jndi-name>
        </session>
    </enterprise-beans>
</openejb-jar>

EJB应用程序部署在ID为dw/simple-ejb-app/1.0/jar 。 请注意,我们将使用moduleId元素下的信息来映射到此应用程序中的EJB,正如我们将在本文后面看到的那样。

一个演示EJB安全性的简单Web应用程序

在本文中,我们使用一个简单的Web应用程序来演示EJB安全性。 Web应用程序使用两个安全角色,即“ bank ”和“ customer ”。 该Web应用程序由一个具有不受限制的访问权限的主页和两个可通过“ bank ”和“ customer ”角色访问的安全页面组成。 每个页面都访问SimpleSessionBeanSimple3ServiceBean方法,并显示该方法的结果或方法调用时引发的任何异常。 清单4显示了web.xml部署描述符。

清单4:简单的Web应用程序部署描述符
<web-app ...>
    <display-name>simple-web-app</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        ...
    </welcome-file-list>

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>Not required for FORM auth</realm-name>
        <form-login-config>
            <form-login-page>/login/login.jsp</form-login-page>
            <form-error-page>/login/loginerror.jsp</form-error-page>
        </form-login-config>
    </login-config>

    <security-role>
        <role-name>customer</role-name>
    </security-role>
    <security-role>
        <role-name>bank</role-name>
    </security-role>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Customer</web-resource-name>
            <url-pattern>/customer/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>customer</role-name>
                 <!-- This comes from the security-role element -->
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Bank</web-resource-name>
            <url-pattern>/bank/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>bank</role-name> 
                   <!-- This comes from the security-role element -->
        </auth-constraint>
    </security-constraint>

    <ejb-ref>
        <ejb-ref-name>ejb/SimpleService</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>simple.ejb21.SimpleServiceHome</home>
        <remote>simple.ejb21.SimpleService</remote>
    </ejb-ref>
    <ejb-ref>
        <ejb-ref-name>ejb/Simple3Service</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <remote>simple.ejb3.Simple3Service</remote>
    </ejb-ref>
    ....
</web-app>

Web应用程序使用在login-config元素中配置的FORM身份验证。 这两个安全角色是使用security-role元素定义的。 我们使用security-constraint标签为资源集合配置安全权限。 在此示例中,具有bank角色的用户可以使用/bank/*模式访问URL,而具有customer角色的customer可以使用/customer/*模式访问URL。

我们使用ejb-ref元素声明EJB引用,以通过其远程本地和远程接口访问Bean。 在此样本中,我们定义了两个EJB引用,即ejb/SimpleServiceejb/Simple3Service 。 注意,没有为Simple3Service bean(它是EJB3会话bean)定义home接口。 您可以使用ejb-local-ref 元素,用于声明用于通过其本地home和本地接口访问bean的EJB引用。

geronimo-web.xml Web应用程序部署计划中,我们将web.xml定义的EJB引用映射到特定的EJB,并将安全角色映射到主体。 清单5显示了示例Web应用程序的部署计划。

清单5:简单的Web应用程序部署计划
<web-app ...>
    ...
    <context-root>simple-web-app</context-root>
    <nam:ejb-ref xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2">
        <nam:ref-name>ejb/SimpleService</nam:ref-name>
        <nam:pattern>
            <nam:groupId>dw</nam:groupId>
            <nam:artifactId>simple-ejb-app</nam:artifactId>
            <nam:version>1.0</nam:version>
            <nam:name>SimpleSessionBean</nam:name>
        </nam:pattern>
    </nam:ejb-ref>
    <nam:ejb-ref xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2">
        <nam:ref-name>ejb/Simple3Service</nam:ref-name>
        <nam:pattern>
            <nam:groupId>dw</nam:groupId>
            <nam:artifactId>simple-ejb-app</nam:artifactId>
            <nam:version>1.0</nam:version>
            <nam:name>Simple3ServiceBean</nam:name>
        </nam:pattern>
    </nam:ejb-ref>
    ...
    <security-realm-name>SampleSecurityRealm</security-realm-name>
    <app:security ...>
        ...
        <sec:role-mappings>
            <sec:role role-name="customer">
                <sec:principal name="UserGrp" 
                    class="o.a.g.s.r.providers.GeronimoGroupPrincipal"/>
                ...
            </sec:role>
            <sec:role role-name="bank">
                <sec:principal name="AdminGrp" 
                    class="o.a.g.s.r.providers.GeronimoGroupPrincipal"/>
            ...
            </sec:role>
        </sec:role-mappings>
    </app:security>
</web-app>

我们使用ejb-ref 将EJB引用映射到特定EJB的元素。 在此示例中,请注意ejb-refref-name元素中的值 在的值相匹配ejb-ref-name下元件ejb-refweb.xml (参见清单4 )。 同样,我们使用ejb-local-ref元素将EJB本地引用映射到特定的EJB。

security-realm-name元素用于配置应用程序对其进行身份验证的安全领域。 在此示例中,我们使用名称为SampleSecurityRealm的领域。

安全角色映射到security元素内的role-mappings元素下的主体。 我们将role元素用于要映射的每个安全角色。 安全角色role-namerole元素的role-name属性中指定。 我们使用角色元素内的主体元素指定映射到安全角色的主体。 在此示例中,我们将bank角色映射到名称为AdminGrpGeronimoGroupPrincipal以及customer 名称为UserGrpGeronimoGroupPrincipal角色。 请参阅参考资料中提供的WebSphere Application Server Community Edition V2.0中的配置Web应用程序安全性,以详细说明角色映射的主体。

在没有EJB安全性的情况下运行示例应用程序

现在,我们将运行访问EJB应用程序中EJB的简单Web应用程序。 请注意,目前我们还没有为EJB配置安全性。 在继续进行操作之前,将样本存档下载并解压缩到您选择的目录中(我们将此目录称为<SAMPLES_HOME> ),然后将dw_users.properties和dw_groups.properties文件复制到<WASCE_HOME> /var/security目录( <WASCE_HOME>是指Community Edition安装目录。

要运行示例应用程序:

  1. 启动Community Edition,然后在浏览器中打开http://localhost:8080/console/
  2. 输入system作为用户名 ,输入manager作为密码 。 单击登录 ,这将在管理控制台中打开“欢迎”页面。
  3. 浏览至Deploy New portlet。
  4. 在“ 计划”字段下,导航到<SAMPLES_HOME>并选择文件SampleSecurityRealm-plan.xml
  5. 单击安装以完成安全领域部署。
  6. 在“ 存档”字段下,导航到<SAMPLES_HOME>并选择simple-ejb-app.jar
  7. 单击安装以完成EJB应用程序部署。
  8. 在“存档”字段下,导航到<SAMPLES_HOME>并选择simple-web-app.war
  9. 单击“ 安装”以完成Web应用程序部署。
  10. 访问http://localhost:8080/simple-web-app ,该屏幕显示图1中的屏幕。
    图1:Web应用程序主页
    Web应用程序主页的屏幕截图

    用户信息”部分显示了Web应用程序中当前登录的用户的UserPrincipalUser RolesEJB2.1部分显示了调用SimpleSessionBean每个方法的结果。 EJB3部分显示了调用Simple3ServiceBean每个方法的结果。 由于我们尚未登录该应用程序,因此UserPrincipalUserRole为空。 由于没有为任何EJB方法配置安全性,因此所有方法都是可访问的,并以未经身份验证的用户身份调用。

  11. 访问http://localhost:8080/simple-web-app/bank 。 使用密码admin以用户dwadmin登录,该密码显示在图2中。
    图2:Web应用程序银行页面
    Web应用程序银行页面的屏幕截图

    请注意, UserPrincipal将登录用户dwadminUserRole显示bank 。 由于没有为任何EJB方法配置安全性,因此所有方法都是可访问的,并以未经身份验证的用户身份调用。

到目前为止,我们已经看到Web应用程序通过不受限制的方法访问来调用EJB2.1和EJB3会话Bean。 接下来,我们将配置EJB2.1和EJB3会话Bean的方法权限。

EJB2.1部署描述符中的安全性配置

EJB应用程序将基于角色的安全性用于bean级和方法级安全性。 在本节中,我们将了解如何定义安全角色和配置方法权限。

定义安全角色

我们使用assembly-descriptor下的security-role元素在部署描述符文件ejb-jar.xml定义安全角色。 role-name元素指定安全角色的名称。 清单6显示了本文中使用的示例应用程序之一的ejb-jar.xml的摘录。

清单6:显示角色定义的汇编描述符
<ejb-jar ...>
    <display-name>SimpleEjbApp</display-name>
    <enterprise-beans>
    ...
    </enterprise-beans>
    <assembly-descriptor>
      <security-role>
         <description>User role</description>
         <role-name>ejbuser</role-name>
      </security-role>
      <security-role>
         <description>Administrator role</description>
         <role-name>ejbadmin</role-name>
      </security-role>
      ...
    </assembly-descriptor>
</ejb-jar>

在此示例中,应用程序定义了两个角色,即ejbuserejbadmin

配置方法权限

为了配置安全身份以调用EJB中的方法,我们在ejb-jar.xml enterprise-beans元素下的bean定义中使用了security-identity元素。 我们通过使用ejb-jar.xml assembly-descriptor下的method-permission元素来配置Bean方法权限。 清单7显示了用于配置SimpleSessionBean的方法许可权的EJB应用程序部署描述符的片段。

清单7:EJB应用程序部署描述符
<ejb-jar id="SimpleEjbAppWithSecurity" ...>
    <enterprise-beans>
        <session>
            ...
            <ejb-name>SimpleSessionBean</ejb-name>
            ...
            <security-identity>
                <use-caller-identity />
            </security-identity>
        </session>
        ...
    </enterprise-beans>
    <assembly-descriptor>
        <security-role>
        ...
        </security-role>
        <method-permission>
            <role-name>ejbuser</role-name>
            <method>
                <ejb-name>SimpleSessionBean</ejb-name>
                <method-name>userMethod</method-name>
            </method>
        </method-permission>
        <method-permission>
            <role-name>ejbadmin</role-name>
            <method>
                <ejb-name>SimpleSessionBean</ejb-name>
                <method-name>adminMethod</method-name>
            </method>
        </method-permission>
        <method-permission>
            <unchecked/>
            <method>
                <ejb-name>SimpleSessionBean</ejb-name>
                <method-name>commonMethod</method-name>
            </method>
        </method-permission>
        <method-permission>
            <role-name/>
            <method>
                <ejb-name>SimpleSessionBean</ejb-name>
                <method-name>noaccessMethod</method-name>
            </method>
        </method-permission>
    </assembly-descriptor>
</ejb-jar>

让我们看一下在此示例中使用的标签:

  • security-identity元素指定用于调用SimpleSessionBean方法的安全性标识。
  • use-caller-identity元素指定将调用者的安全身份用作执行企业bean方法的安全身份。 另一种选择是使用run-as 元素,用于指定使用运行身份来调用Bean的方法,如本文稍后所述。
  • method-permission's method元素指定Bean中一个或多个方法的安全权限。
  • 您可以使用一个或多个role-name元素来指​​定权限,每个允许访问该方法的角色都可以指定一个。 单个空的role-name元素表示该角色无权访问该方法。 您可以使用unchecked元素来指​​定不受限制的访问权限。
  • 方法的ejb-name元素指定EJB的名称。 method-name元素指定method-namemethod-name“*”对应于EJB中的所有方法。
  • 特定的method-name对应于该名称的所有方法,包括任何重载方法。 要从重载方法中指定特定方法,请使用method-params元素。
  • 您可以在Bean的Home,Remote,Local和LocalHome接口中为方法配置method-permission 。 要在特定接口中指定方法的许可权,请在method下的method-intf元素中使用相应的值。

在清单7中,在SimpleSession bean中,我们配置了:

  • userMethod是通过访问ejbuser作用。
  • adminMethod是通过访问ejbadmin作用。
  • c ommonMethod具有不受限制的访问。
  • noaccessMethod不能由任何角色访问。

使用注释在EJB3 bean中进行安全性配置

在EJB3企业bean中,可以使用安全注释配置bean级和方法级安全性。 在本节中,我们讨论各种安全注释( @DeclareRoles, @DenyAll, @PermitAll, @RolesAllowed )以及它们如何影响安全配置。 请注意,我们将在本文后面讨论@RunAs批注。

定义安全角色

您可以通过在bean类上使用@DeclareRoles注释来定义安全角色,如清单8所示。

清单8:具有@DeclareRoles批注的Simple3ServiceBean
@Stateless
@DeclareRoles({"ejb3user", "ejb3admin"})
public class Simple3ServiceBean implements Simple3Service {
...
}

在此示例中, Simple3ServiceBean定义了两个安全角色,即ejb3userejb3admin

配置方法权限

您可以使用@DenyAll, @PermitAll@RolesAllowed批注配置企业bean方法的权限。 @PermitAll@RolesAllowed批注可以应用于bean类以及bean方法,而@DenyAll批注只能应用于bean方法。 应用于类的注释适用于该类中的所有方法。 应用在方法上的注释会覆盖应用在类上的所有注释。 清单9显示了Simple3ServiceBean类。

清单9:具有安全注释的Simple3ServiceBean类
@Stateless
@DeclareRoles({"ejb3user", "ejb3admin"})
public class Simple3ServiceBean implements Simple3Service {

	  @Resource
	  private SessionContext ctx;
	
        @PermitAll
	  public String commonMethod() {
		  return logCall("commonMethod");
	  }

        @RolesAllowed({"ejb3user"})
	  public String userMethod() {
		  return logCall("userMethod");
	  }

        @RolesAllowed({"ejb3admin"})
	  public String adminMethod() {
		  return logCall("adminMethod");
	  }
	  
        @DenyAll
	  public String noaccessMethod() {
		  return logCall("noaccessMethod");
	  }
	  
	  private String logCall(String method) {
              ...
		  return msg;
	  }
}

本示例定义以下访问配置:

  • commonMethod具有不受限制的访问。
  • 通过ejb3user角色可以访问userMethod
  • adminMethod可由ejb3admin角色访问。
  • 任何角色均无法访问noaccessMethod

EJB部署计划中的安全角色映射

EJB部署描述符中定义的安全角色和使用@DeclareRoles批注定义的角色被映射到EJB部署计划openejb-jar.xml.中的主体openejb-jar.xml. 显示了EJB部署计划中主体到角色的映射。

清单10:主体到角色的映射
<security>
    <role-mappings>
        <role role-name="ejbuser">
            <principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal" 
                  name="UserGrp"/>
        </role>
        <role role-name="ejbadmin">
            <principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal" 
                  name="AdminGrp"/>
        </role>
        <role role-name="ejb3user">
            <principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal"
                  name="UserGrp"/>
        </role>
        <role role-name="ejb3admin">
            <principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal" 
                  name="AdminGrp"/>
            <principal class="o.a.g.s.r.providers.GeronimoUserPrincipal" 
                  name="dwuser3"/>
        </role>
    </role-mappings>
</security>

请注意, ejb-jar.xml@DeclareRoles批注中的安全角色已映射到主体:

  • ejbuser角色映射到名称为“UserGrp”GeronimoGroupPrincipal
  • 我们将ejbadmin角色映射到名称为“AdminGrp”GeronimoGroupPrincipal
  • ejb3user角色映射到名称为“UserGrp”GeronimoGroupPrincipa
  • ejb3admin角色映射到GeronimoGroupPrincipal与名称“AdminGrp”GeronimoUserPrincipal名称为“dwuser3”

有关主体到角色映射的详细说明,请参阅WebSphere Application Server社区版V2.0中的配置Web应用程序安全性

使用EJB安全性运行示例应用程序

浏览至Deploy New portlet。

  1. 在“ 存档文件”下,导航到< SAMPLES_HOME >,然后选择simple-ejb-app-w-security.jar。
  2. 选择重新部署应用程序选项,然后单击安装
  3. 导航到Web App WARs portlet并启动dw / simple-web-app / 1.0 / war
  4. 访问http://localhost:8080/simple-web-app ,它显示了图3中的屏幕。
    图3:访问安全EJB的Web应用程序主页
    主页访问安全EJB的屏幕截图

    请注意,由于用户尚未登录应用程序,因此只能从主页调用SimpleSessionBeanSimple3ServiceBean commonMethod (具有不受限制的访问权限)。 所有其他方法调用都导致AccessExceptionEJBAccessException因为未经授权的Principal

  5. 访问http://localhost:8080/simple-web-app/bank/ 。 使用密码admin登录名为dwadmin用户,该密码显示在图4中。
    图4:访问安全EJB的Web应用程序银行页面
    银行页面访问安全EJB的屏幕截图

    由于用户现在登录为dwadmin ,该Subject包含GeronimoUserPrincipal与名称dwadminGeronimoGroupPrincipal与名称AdminGrp 。 用户根据角色映射映射到ejbadminejb3admin角色。 因此,用户可以访问commonMethod,具有无限制访问,并adminMethod ,这是访问(由ejbadmin角色SimpleSessionBeanejb3admin的角色Simple3ServiceBean )。 调用时, userMethodnoaccessMethod导致AccessExceptionEJBAccessExceptionuserMethod可以通过ejbuser角色( ejb3user角色) Simple3ServiceBeannoaccessMethod不能由任何角色访问,

  6. 打开一个新的浏览器窗口,然后访问http://localhost:8080/simple-web-app/customer/ 。 使用密码user3登录名为dwuser3用户,该密码显示在图5中。
    图5:访问安全EJB的Web应用程序客户页面
    客户页面访问安全EJB的屏幕截图

    由于用户现在以dwuser3登录,因此Subject包含名称为dwuser3 GeronimoUserPrincipalGeronimoGroupPrincipal ,名称为UserGrp 。 用户根据角色映射映射到ejbuserejb3userejb3admi n角色。 在SimpleSessionBean ,用户可以访问commonMethod,具有不受限制的访问权限)和可以通过ejbuse r角色访问的userMethod 。 在Simple3ServiceBean中,用户可以访问commonMethod,具有无限制访问的userMethod即由可访问ejb3user作用和adminMetho d是通过访问ejb3admin作用(见在EJB2.1部署描述符安全配置 )。 所有其他方法在调用时都导致AccessExceptionEJBAccessException

运行方式和默认主题

除了为bean的方法配置方法权限之外,还可以为bean配置Run-as身份,以指定bean调用其他bean的安全身份。 当bean的方法需要调用其他安全标识与调用它的安全标识不同的其他bean时,例如,消息驱动的bean方法(不带任何安全标识调用)调用安全的会话bean时,此配置很有用。方法。 您可以配置安全凭据,这些凭据构成了部署计划中运行角色安全性的主题。

在2.0之前的Community Edition版本中,运行方式和默认主题的安全性配置是使用使用default-principal标签和default-principal designated-run-as属性指定的主体和凭证构造的。 从Community Edition 2.0开始,所有安全性都源于登录到安全领域所产生的主题。 要使用这些主题,您需要提供每个此类主题的登录信息。 此登录信息在凭据存储中捕获。

凭证存储

Community Edition提供了凭据存储的实现,即SimpleCredentialStoreImpl ,它使您可以在部署计划中使用XML配置凭据存储。 清单11显示了我们在本文的示例应用程序中使用的凭证存储。

清单11:凭证存储gbean
<gbean name="SampleCredentialStore" 
      class="o.a.g.s.credentialstore.SimpleCredentialStoreImpl" ...>
    <xml-attribute name="credentialStore">
        <credential-store 
              xmlns="http://geronimo.apache.org/xml/ns/credentialstore-1.0">
            <realm name="SampleSecurityRealm">
                <subject>
                <id>dwuser1-subject</id>
                    <credential>
                        <type>o.a.g.s.credentialstore.NameCallbackHandler</type>
                        <value>dwuser1</value>
                    </credential>
                    <credential>
                        <type>o.a.g.s.credentialstore.PasswordCallbackHandler</type>
                        <value>user1</value>
                    </credential>
                </subject>
                <subject>
                    <id>dwuser2-subject</id>
                    ...
                </subject>
                <subject>
                    <id>dwuser3-subject</id>
                    ...
                </subject>
                <subject>
                    <id>dwadmin-subject</id>
                    ...
                </subject>
            </realm>
            <realm name="AnotherRealm">
                <subject>
                ...
                </subject>
                ...
            </realm>
        </credential-store>
    </xml-attribute>
</gbean>

在这里, name的属性realm元素指定的名称security-realm ,你用它来创建subjec吨。 该id下元素subject元素指定的ID subject ,可与结合使用security-realm的名称配置运行的主体和缺省主体为我们后来显示的时候。

您可以在subject下使用credential元素来配置security-realm的登录信息。 在清单11中,我们获得使用用户名dwuser1和密码user1登录到SampleSecurityRealm dwuser1-subject 。 当前,Community Edition提供了用于名称和密码的回调处理程序,足以使用需要名称和密码进行身份验证的安全领域。 要对凭据存储使用其他安全领域,例如使用数字证书的领域,则需要实现所需的回调处理程序。 此外,凭据存储可以是每个应用程序,也可以有一个凭据存储供所有应用程序使用。

配置应用程序以使用凭据存储

您可以在应用程序的部署计划中的安全配置中指定应用程序要使用的凭据存储。 清单12显示了本文中使用的示例应用程序之一的安全性配置。

清单12:显示credential-store-ref的安全配置
<security>
    <credential-store-ref>
        <name xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2">
             SampleCredentialStore</name>
    </credential-store-ref>
    ...
</security>

在此示例中, credential-store-ref下的name元素指定应用程序要使用的凭据存储。 请注意,此值与清单11中所示的凭证存储gbean的name属性匹配。

配置运行方式和默认主题

您可以在应用程序的部署计划的安全性配置中为应用程序指定运行方式和默认主题。 如果没有为任何角色配置运行主题,则将使用配置的默认主题。 清单13显示了本文中使用的示例应用程序之一的运行方式和默认主题配置。

清单13:显示运行方式和默认主题的安全性配置
<security>
    ...
    <default-subject>
        <realm>SampleSecurityRealm</realm>
        <id>dwuser1-subject</id>
    </default-subject>
    <role-mappings>
        <role role-name="ejb3user">
            <run-as-subject>
                <realm>SampleSecurityRealm</realm>
                <id>dwuser3-subject </id>
            </run-as-subject>
            <principal class="o.a.g.s.r.providers.GeronimoGroupPrincipal" name="UserGrp"/>
        </role>
        <role role-name="another">
        ...
        </role>
        ...
    </role-mappings>
</security>

default-subject security元素下的元素可配置应用程序使用的默认主题。 default-subject下的realm元素指定安全领域,而id元素指定在凭证存储中配置的主题的ID。 请注意,在default-subject下为该realm指定的值与清单11中的realm元素的name属性匹配。另外,请注意,在default-subject下为该id指定的值与清单11中的主题id之一匹配。

run-as-subject的要素role下元素role-mappings配置运行为主体的那个角色。 清单13显示了为ejb3user角色配置的运行主题。 注意,在run-as-subject下为realm指定的值与清单11中的realm元素的name属性匹配。另外,请注意,在run-as-subjec t下为id指定的值与清单11中的主题id之一匹配。

具有运行方式的示例EJB应用程序

我们又添加了两个会话bean( Simple3ServiceBean2Simple3SeviceBean3 ),它们依次调用Simple3ServiceBean的相应方法。 我们将Simple3ServiceBean2配置为以ejb3user角色运行。 Simple3ServiceBean3未配置运行角色。 清单14显示了Simple3ServiceBean2 bean类。

清单14:Simple3ServiceBean2类
@Stateless
@DeclareRoles(value = {"ejb3user", "ejb3admin"})
@RunAs("ejb3user")
public class Simple3ServiceBean2 implements Simple3Service2 {

	  @EJB
	  private Simple3Service simple; // Simple3Service injected here
	
        @PermitAll
	  public String commonMethod() {
          Object temp;
          try {
              temp = simple.commonMethod();
          } catch(Throwable t) {
              temp = t;
          }
          return logCall("commonMethod") + "::" + temp;
	  }

        @RolesAllowed({"ejb3user"})
	  public String userMethod() {
            ...
	  }

        @RolesAllowed({"ejb3admin"})
	  public String adminMethod() {
            ...
	  }
	  
        @DenyAll
	  public String noaccessMethod() {
            ...
	  }
	  
      private String logCall(String method) {
            ...
	  }
}

在这个例子中,我们使用了@RunAs注释与ejb3user角色配置运行作为角色Simple3ServiceBean2 。 使用此配置,在Simple3Service上的方法调用使用部署计划中指定的run-as-subject。 请注意, ejb3user角色的按主题运行被指定为dwuser3-subject (请参见清单13)。

使用运行时EJB安全性运行示例应用程序

  1. 浏览至Deploy New portlet。
  2. 部署示例中提供的simple-ejb-app-w-runas.jar 。 在单击“ 安装”之前,请确保选择“ 重新部署”应用程序选项。
  3. 导航到Web App WARs portlet并启动dw / simple-web-app / 1.0 / war
  4. 访问http://localhost:8080/simple-web-app 。 向下滚动至RunAs部分,该部分显示图6中的屏幕。
    图6:Web应用程序主页以运行方式访问EJB
    带有运行方式的主页的屏幕截图

    请注意,在RunAs部分下,以未经身份验证的用户身份调用Simple3ServiceBean2中的commonMethod ,但是按照run-as-subject的配置,依次将Simple3ServiceBean中的dwuser3作为commonMethod进行调用。 由于Simple3ServiceBean3未配置运行角色,因此Simple3ServiceBeancommonMethod作为未经身份验证的用户来调用。

  5. 访问http://localhost:8080/simple-web-app/customer/ 。 使用密码user1以名称dwuser1登录。 向下滚动至RunAs部分,该部分显示图7中的屏幕。
    图7:Web应用程序客户页面以运行方式访问EJB
    具有运行方式的客户页面的屏幕截图

注意,在RunAs部分下, Simple3ServiceBean2中的commonMethoduserMethod作为dwuser 1调用,当前用户已登录到Web应用程序。 但是,按照run-as-subject的配置,依次将Simple3ServiceBean中的commonMethoduserMethod作为dwuser3调用。 由于未为Simple3ServiceBean3配置运行身份角色,因此Simple3ServiceBean中的commonMethoduserMethod将作为dwuser1调用。

配置实体bean安全

您可以使用部署描述符和安全批注来配置实体Bean安全性,方法与会话Bean安全性相同。 清单15显示了带有实体bean的示例EJB应用程序中的组装描述符。

清单15:汇编描述符
<assembly-descriptor>
       <security-role>
           <description>Bank Manager</description>
           <role-name>manager</role-name>
       </security-role>
       <method-permission>
           <role-name>manager</role-name>
           <method>
               <ejb-name>MyBank</ejb-name>
               <method-name>create</method-name>
           </method>
       </method-permission>
   </assembly-descriptor>

在此示例中,我们将MyBank实体bean的Home接口上的create方法配置为只能由manager角色访问。

运行实体bean示例应用程序

样本中提供的MyBankEJB样本应用程序包含一个名为MyBank EJB2.1实体bean。 我们将bean的LocalHomeHome接口中的create方法配置为只能由manager访问 角色。

请按照以下步骤运行应用程序:

  1. 浏览至Deploy New portlet。
  2. 在“ 存档”字段中,浏览至< SAMPLES_HOME >并选择bank-db-pool.rar。
  3. 单击“ 安装”以部署MyBankEJB应用程序使用的数据库池。
  4. 在“ 存档”字段中,浏览到< SAMPLES_HOME >并选择MyBankEJB.jar。
  5. 单击安装以部署MyBankEJB应用程序。
  6. 在“ 存档”字段中,浏览到< SAMPLES_HOME >并选择MyBankWeb.war。
  7. 单击“ 安装”以部署MyBankWeb应用程序。
  8. 访问http://localhost:8080/MyBankWeb.

    请注意,显示的页面显示在“ 创建帐户” 部分中发生了异常,因为用户尚未登录。

  9. 现在访问http://localhost:8080/MyBankWeb/manager

请注意,现在显示的页面显示帐户创建成功。 它之所以成功,是因为该页面使用运行角色配置为使用用户ID dwadmin访问MyBank bean,该ID映射到MyBankEJB部署计划中配置的manager角色。

配置消息驱动的Bean安全性

与会话和实体Bean不同,消息驱动的Bean不会被其他Bean或客户端应用程序调用。 当消息到达侦听器正在监视的输入目标时,它们将由JMS侦听器调用。 消息驱动的Bean可以调用其他会话和实体Bean。 要从消息驱动的Bean调用安全EJB,需要为消息驱动的Bean配置运行身份。 对于EJB2.1消息驱动的bean,可以使用部署描述符中的security-identity元素配置运行方式角色。 对于EJB3消息驱动的bean,您可以使用@RunAs注释配置运行角色。

运行消息驱动的Bean示例应用程序

为了演示EJB3消息驱动bean的运行时安全性,我们在jms-mdb-sample-ear-2.1.0.1.ear)提供了一个应用程序( jms-mdb-sample-ear-2.1.0.1.ear) 。 该应用程序由一个称为OrderRecvMDB消息驱动的bean和一个名为OrderRecvMDB的无状态会话bean Simple30ServiceBean 。 我们将会话bean的userMethod配置为可以由ejb3user角色访问,并且将OrderRecvMDB bean配置为具有运行身份ejb3user 。 在部署计划中,安全配置为ejb3user角色指定一个按主题运行dwuser1-subject 。 清单16显示了OrderRecvMDB bean类:

清单16:OrderRecvMDB bean类
import javax.annotation.security.RunAs;
...

//
// MessageDrivenBean that listens to items on the
// 'OrderQueue' queue and processes them accordingly.
//
@MessageDriven(activationConfig = {
       @ActivationConfigProperty(propertyName="destinationType", 
           propertyValue="javax.jms.Queue"),
       @ActivationConfigProperty(propertyName="destination", 
           propertyValue="OrderQueue")
   })
@RunAs("ejb3user")               
public class OrderRecvMDB implements MessageListener {
	
	@EJB
	private Simple30Service simple; // Session bean is injected

	/*
     * Process a message.
     * 
     * @param message The message to process. 
     */
    public void onMessage(Message message) {
        TextMessage textMessage = (TextMessage) message;
        try {
            System.out.println("Order Received \n"+ textMessage.getText());
            simple.userMethod();
        } catch ( JMSException e ) {
            e.printStackTrace();
        }
    }
}

请按照以下步骤运行应用程序:

  1. 浏览至Deploy New portlet。
  2. 在“ 存档”字段中,浏览到< SAMPLES_HOME >并选择jms-mdb-sample-ear-2.1.0.1.ear
  3. 单击安装以部署示例应用程序。
  4. 访问http://localhost:8080/order
  5. 输入字段值,然后单击订购

请注意,服务器控制台窗口中显示的顺序与安全标识的细节一起接收dwuser1与该userMethodSimple30ServiceBean被调用。

结论

我们创建了EJB2.1和EJB3会话Bean,一个EJB2.1实体Bean,并使用部署描述符和安全注释为Bean方法配置了访问权限。 我们还为会话和消息驱动的bean配置了运行方式角色,并创建了必要的工件(如凭证存储)来部署使用此安全配置的EJB应用程序。 我们还使用示例Web应用程序调用EJB演示了EJB安全性。

致谢

感谢Phani Madgula审阅了此材料。


翻译自: https://www.ibm.com/developerworks/websphere/library/techarticles/0811_vamsi/0811_vamsi.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值