2017-02-08 74 views
0

我首次開發(嘗試..)採用EJB的安全功能的JavaEE應用。 我正在使用WildFly 10.1。 我已經創建了一個Jdbc安全域並配置了一個基於表單的登錄。訪問Web方法和URL路徑以及登錄工作權限(防止未經授權訪問並在登錄後授權訪問)。JAX-RS + EJB,SecurityContext的內部EJB爲空,在WildFly 10.1

我有一組豆實現了(JAX-RS)REST接口和我有一組EJB無狀態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代碼並混淆了我的「用例」相關名稱。一個JAX-RS豆 例子:

@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類到 EJB豆的安全上下文?
  • 安全信息是否像我預期的那樣被神奇地管理?或..
  • 我是否需要改進或添加其他jboss - ?. xml配置文件? 或..
  • 我有沒有改變在調用JAX-RS豆的東西,以 傳播安全信息的叫豆?或..
  • 或者我做錯了什麼?

預先感謝您 問候

+0

這個問題是下面的解決方案的來源,我添加了一些有用的細節(缺乏來源),希望有用。 –

+1

只是爲了回答你的前兩個要點,容器負責*傳播安全上下文,你通常不需要關心這一點。 –

回答

0

我已經找到了答案,這個問題已經被問here

的SecurityContext只爲JAX-RS豆,你需要注入的EJBContext的對象就地將SecurityContext一個轉換爲其他java bean。 您也可以使用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); 
    } 
}