我正在尝试部署一个企业应用程序 EAR,其中包括:
- 包含无状态会话 bean 的 EJB 3.1 模块
- 一个包含 servlet 的 web 模块
到 Apache Geronimo V3.0(打包为 WebSphere Community 3.0.0.4 服务器)。
bean 通过@LocalBean 注释公开,并使用@EJB 注释注入到servlet 中。
如果没有定义任何应用程序安全设置,一切都可以完美运行。但是,一旦我定义了最简单的安全设置,注入就会失败并显示以下消息:
java.lang.IllegalArgumentException:无效的方法接口:LocalBean javax.security.jacc.EJBMethodPermission$MethodSpec.checkMethodInterface(EJBMethodPermission.java:303) javax.security.jacc.EJBMethodPermission$MethodSpec.(EJBMethodPermission.java:209) javax.security。 jacc.EJBMethodPermission.(EJBMethodPermission.java:90) org.apache.geronimo.openejb.GeronimoSecurityService.isCallerAuthorized(GeronimoSecurityService.java:100) org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:159) org .apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:255) org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:235) org.apache.openejb.core.ivm.EjbObjectProxyHandler ._invoke(EjbObjectProxyHandler.java:92) org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:284) com.sun.proxy.$Proxy117.getSysTime(未知来源) dk.danicon.servlet.Systime.doGet(Systime.java: 43) javax.servlet.http.HttpServlet.service(HttpServlet.java:575) javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
安全配置完美运行,并提示使用如下注释定义的 servlet 上的凭据,如果它们不尝试注入 EJB:
@ServletSecurity(@HttpConstraint(rolesAllowed={"admin"}))
我可以通过删除@LocalBean 并实现@Local 接口来使注入工作。但是,从我能够阅读的关于该主题的内容来看,这也应该适用于无界面视图 - 我想避免界面的额外开销。
我在下面附上了相关的配置文件,希望有人能告诉我我在这里缺少什么?
application.xml(EAR 模块):
<?xml version="1.0" encoding="UTF-8"?>
<application id="Application_ID" version="6" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd">
<display-name>TestEar</display-name>
<module id="Module_1383740442312">
<web>
<web-uri>TestWeb.war</web-uri>
<context-root>test</context-root>
</web>
</module>
<module id="Module_1383741874882">
<ejb>TestEjb.jar</ejb>
</module>
</application>
geronimo-application.xml(EAR 模块):
<?xml version="1.0" encoding="UTF-8"?>
<app:application xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" application-name="TestEar" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>application</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
<dep:dependencies>
<dep:dependency>
<dep:groupId>org.apache.geronimo.framework</dep:groupId>
<dep:artifactId>j2ee-security</dep:artifactId>
<dep:type>car</dep:type>
</dep:dependency>
<dep:dependency>
<dep:groupId>console.dbpool</dep:groupId>
<dep:artifactId>jdbc_ssodb</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
</dep:dependencies>
</dep:environment>
<sec:security>
<sec:role-mappings>
<sec:role role-name="admin">
<sec:principal class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" name="ADMIN"/>
</sec:role>
</sec:role-mappings>
</sec:security>
<dep:gbean class="org.apache.geronimo.security.realm.GenericSecurityRealm" name="webrealm">
<dep:attribute name="realmName">webrealm</dep:attribute>
<dep:reference name="ServerInfo">
<dep:name>ServerInfo</dep:name>
</dep:reference>
<dep:xml-reference name="LoginModuleConfiguration">
<log:loginConfig>
<log:login-module control-flag="REQUIRED" wrap-principals="false">
<log:login-domain-name>webrealm</log:login-domain-name>
<log:login-module-class>org.apache.geronimo.security.realm.providers.SQLLoginModule</log:login-module-class>
<log:option name="dataSourceName">jdbc/ssodb</log:option>
<log:option name="userSelect">SELECT username, password FROM v4.app_users WHERE username = ?</log:option>
<log:option name="groupSelect">SELECT username, group_name FROM v4.app_users WHERE username = ?</log:option>
<log:option name="digest"/>
<log:option name="encoding"/>
</log:login-module>
</log:loginConfig>
</dep:xml-reference>
</dep:gbean>
</app:application>
ejb-jar.xml(EJB 模块):
<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd">
<display-name>TestEjb </display-name>
</ejb-jar>
openejb-jar.xml(EJB 模块):
<?xml version="1.0" encoding="UTF-8"?>
<ejb:openejb-jar xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0" xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>ejbmodule</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
</dep:environment>
</ejb:openejb-jar>
web.xml(WEB模块):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>TestWeb</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>webrealm</realm-name>
</login-config>
</web-app>
geronimo-web.xml(WEB 模块):
<?xml version="1.0" encoding="UTF-8"?>
<web:web-app xmlns:web="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1" xmlns:app="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:client="http://geronimo.apache.org/xml/ns/j2ee/application-client-2.0" xmlns:conn="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:ejb="http://openejb.apache.org/xml/ns/openejb-jar-2.2" xmlns:jaspi="http://geronimo.apache.org/xml/ns/geronimo-jaspi" xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-2.0" xmlns:name="http://geronimo.apache.org/xml/ns/naming-1.2" xmlns:pers="http://java.sun.com/xml/ns/persistence" xmlns:pkgen="http://openejb.apache.org/xml/ns/pkgen-2.1" xmlns:sec="http://geronimo.apache.org/xml/ns/security-2.0">
<dep:environment>
<dep:moduleId>
<dep:groupId>dk.danicon</dep:groupId>
<dep:artifactId>webmodule</dep:artifactId>
<dep:version>1.0</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
</dep:environment>
<web:context-root>/test</web:context-root>
<web:security-realm-name>webrealm</web:security-realm-name>
</web:web-app>
示例 EJB:
package dk.danicon.ejb;
import javax.annotation.security.RolesAllowed;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
@Stateless
@LocalBean
@RolesAllowed({"admin"})
public class SysTime {
public SysTime() {
}
public long getSysTime() {
return System.currentTimeMillis();
}
}
样本小服务程序:
package dk.danicon.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.HttpConstraint;
import javax.servlet.annotation.ServletSecurity;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dk.danicon.ejb.SysTime;
@WebServlet("/testsystime")
@ServletSecurity(@HttpConstraint(rolesAllowed={"admin"}))
public class TestSystime extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB
SysTime systime;
public TestSystime() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
pw.println("<html><body><h3>Systime</h3>");
pw.println("<p>System time: " + systime.getSysTime() + " - " + systime.getClass().getName() + "</p>");
if(request.getUserPrincipal() != null)
pw.println("<p>Principal: " + request.getUserPrincipal().getName() + "</p>");
pw.println("</body></html>");
}
}