JAX-RS + EJB,在 WildFly 10.1 上,ejb 中的 SecurityContext 为空
JAX-RS + EJB, SecurityContext inside ejb is null, on WildFly 10.1
我第一次开发 JavaEE 应用程序(尝试..)使用 ejb 安全功能。
我正在使用 WildFly 10.1。
我创建了一个 Jdbc 安全域并配置了一个基于表单的登录。 Web方法和url路径的访问和登录工作权限(防止未经授权的访问,登录后授权访问)。
我有一组实现 (Jax-RS) REST 接口的 bean 和一组实现我的应用程序业务逻辑的 ejb Stateless bean。
这些是 jboss-web.xml 和 web.xml 的片段:
<jboss-web>
<security-domain>myDomain</security-domain>
</jboss-web>
web.xml:
<security-constraint>
<web-resource-collection>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>administrator</role-name>
<role-name>operator</role-name>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config><!-- 3 -->
<auth-method>FORM</auth-method>
<realm-name>myRealm</realm-name>
<form-login-config>
<form-login-page>/public/login.html</form-login-page>
<form-error-page>/public/error.html</form-error-page>
</form-login-config>
</login-config>
下面是实现 REST 接口和 java bean 的代码示例,我删除了 bolerplate 代码并混淆了我的 "use case" 相关名称。
一个 Jax-RS bean 的示例:
@Stateless
@Path("api/my")
public class myFacadeREST {
@EJB
myFacade myFacade;
@Context //injected response proxy supporting multiple threads
private HttpServletResponse response;
@POST
@Consumes({MediaType.APPLICATION_JSON})
public void create(DataStuff entity) {
myFacade.create(entity);
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON})
public DataStuff find(@PathParam("id") String id) {
return myFacade.find(id);
}
}
以及注入的 EJB 的片段,我需要在其中以编程方式访问安全上下文和主体信息:
@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {
@PersistenceContext(unitName = "myPersistencePU")
private EntityManager em;
@Context SecurityContext securityContext;
@Resource SecurityContext sc; //I have tried both :-(
public DataStuff find(Object id) {
//Here I get a NullPointerException, tried both sc and securitycontext
String username = securityContext.getUserPrincipal().getName();
if(username.equals("gino"){
return null;
}
return getEntityManager().find(entityClass, id);
}
}
我尝试过使用和不使用@DeclareRoles、@PermitAll,但securityContext 和sc 变量始终为空。也许我错过了一些东西,但我知道安全信息神奇地通过 bean 调用移动。
问题
- 如何将安全上下文从 Jax-RS class 传播到
ejb bean?
- 安全信息是否像我预期的那样自动神奇地管理?或者..
- 我是否需要改进或添加其他 jboss-?.xml 配置文件?
或者..
- 我是否需要更改调用 Jax-RS bean 中的某些内容以便
将安全信息传播到被调用的 bean?或者..
- 或者我做错了什么?
提前致谢
此致
我找到了答案,这个问题已经被问过了
SecurityContext 仅适用于 JAX-RS bean,您需要将一个 EJBContext 对象注入另一个 java bean 来代替 SecurityContext。
您也可以使用 SessionContext 对象,但 EJBContext 接口类似于 SecurityContext 接口。这是工作版本:
@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {
@PersistenceContext(unitName = "myPersistencePU")
private EntityManager em;
@Resource EJBContext securityContext;
public DataStuff find(Object id) {
//Now the securityContext is != null :-D
String username = securityContext.getCallerPrincipal().getName();
if(username.equals("gino"){
return null;
}
return getEntityManager().find(entityClass, id);
}
}
我第一次开发 JavaEE 应用程序(尝试..)使用 ejb 安全功能。 我正在使用 WildFly 10.1。 我创建了一个 Jdbc 安全域并配置了一个基于表单的登录。 Web方法和url路径的访问和登录工作权限(防止未经授权的访问,登录后授权访问)。
我有一组实现 (Jax-RS) REST 接口的 bean 和一组实现我的应用程序业务逻辑的 ejb Stateless bean。
这些是 jboss-web.xml 和 web.xml 的片段:
<jboss-web>
<security-domain>myDomain</security-domain>
</jboss-web>
web.xml:
<security-constraint>
<web-resource-collection>
<url-pattern>/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>administrator</role-name>
<role-name>operator</role-name>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config><!-- 3 -->
<auth-method>FORM</auth-method>
<realm-name>myRealm</realm-name>
<form-login-config>
<form-login-page>/public/login.html</form-login-page>
<form-error-page>/public/error.html</form-error-page>
</form-login-config>
</login-config>
下面是实现 REST 接口和 java bean 的代码示例,我删除了 bolerplate 代码并混淆了我的 "use case" 相关名称。 一个 Jax-RS bean 的示例:
@Stateless
@Path("api/my")
public class myFacadeREST {
@EJB
myFacade myFacade;
@Context //injected response proxy supporting multiple threads
private HttpServletResponse response;
@POST
@Consumes({MediaType.APPLICATION_JSON})
public void create(DataStuff entity) {
myFacade.create(entity);
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON})
public DataStuff find(@PathParam("id") String id) {
return myFacade.find(id);
}
}
以及注入的 EJB 的片段,我需要在其中以编程方式访问安全上下文和主体信息:
@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {
@PersistenceContext(unitName = "myPersistencePU")
private EntityManager em;
@Context SecurityContext securityContext;
@Resource SecurityContext sc; //I have tried both :-(
public DataStuff find(Object id) {
//Here I get a NullPointerException, tried both sc and securitycontext
String username = securityContext.getUserPrincipal().getName();
if(username.equals("gino"){
return null;
}
return getEntityManager().find(entityClass, id);
}
}
我尝试过使用和不使用@DeclareRoles、@PermitAll,但securityContext 和sc 变量始终为空。也许我错过了一些东西,但我知道安全信息神奇地通过 bean 调用移动。
问题
- 如何将安全上下文从 Jax-RS class 传播到 ejb bean?
- 安全信息是否像我预期的那样自动神奇地管理?或者..
- 我是否需要改进或添加其他 jboss-?.xml 配置文件? 或者..
- 我是否需要更改调用 Jax-RS bean 中的某些内容以便 将安全信息传播到被调用的 bean?或者..
- 或者我做错了什么?
提前致谢 此致
我找到了答案,这个问题已经被问过了
SecurityContext 仅适用于 JAX-RS bean,您需要将一个 EJBContext 对象注入另一个 java bean 来代替 SecurityContext。 您也可以使用 SessionContext 对象,但 EJBContext 接口类似于 SecurityContext 接口。这是工作版本:
@DeclareRoles({"administrator","operator","user"})
@PermitAll
@Stateless
public class myFacade {
@PersistenceContext(unitName = "myPersistencePU")
private EntityManager em;
@Resource EJBContext securityContext;
public DataStuff find(Object id) {
//Now the securityContext is != null :-D
String username = securityContext.getCallerPrincipal().getName();
if(username.equals("gino"){
return null;
}
return getEntityManager().find(entityClass, id);
}
}