2017-04-13 27 views
0

我有三個資源的REST API @RolesAllowed不工作。任何人都可以訪問名爲PublicResource的第一個方法(即匿名訪問)。第二個方法稱爲SecretResource,只能由特定用戶組訪問。最後,稱爲MixedResource的第三個資源具有混合設置,其中一些方法受到保護,一些方法公開供公衆訪問。JAX-RS(澤西2)安全性,@PermitAll如預期

註解@PermitAll和我期待他們雖然@RolesAllowed不起作用。儘管PublicResource使用@PermitAll進行了註釋,但在嘗試訪問它時,我仍然被要求授權。 MixedResource中用@PermitAll註解的方法也是如此。所以基本上,即使我有匿名訪問權限,我的所有資源中的任何地方都會被要求授權。

我就似鯖水狼牙魚4.1運行,我很困惑,因爲我曾在WebLogic上運行12.1.3其他應用程序非常類似的設置,並有註釋和預期一樣。我錯過了什麼或者錯了什麼?看到我下面的完整代碼。

PublicResource.java:

import javax.annotation.security.PermitAll; 
    import javax.ws.rs.GET; 
    import javax.ws.rs.Path; 
    import javax.ws.rs.Produces; 
    import javax.ws.rs.core.MediaType; 

    @Path("public") 
    @PermitAll 
    public class PublicResource { 

     @GET 
     @Produces(MediaType.TEXT_PLAIN) 
     public String itsPublic() { 
      return "public"; 
     } 

    } 

SecretResource.java:

import javax.annotation.security.RolesAllowed; 
    import javax.ws.rs.GET; 
    import javax.ws.rs.core.MediaType; 
    import javax.ws.rs.Path; 
    import javax.ws.rs.Produces; 

    @Path("secret") 
    @RolesAllowed({ "SECRET" }) 
    public class SecretResource { 

     @GET 
     @Produces(MediaType.TEXT_PLAIN) 
     public String itsSecret() { 
      return "secret"; 
     } 

    } 

MixedResource.java:

import javax.annotation.security.PermitAll; 
    import javax.annotation.security.RolesAllowed; 
    import javax.ws.rs.GET; 
    import javax.ws.rs.Path; 
    import javax.ws.rs.Produces; 
    import javax.ws.rs.core.MediaType; 

    @Path("mixed") 
    @PermitAll 
    public class MixedResource { 

     @GET 
     @Path("public") 
     @Produces(MediaType.TEXT_PLAIN) 
     public String itsPublic() { 
      return "public"; 
     } 

     @GET 
     @Path("secret") 
     @RolesAllowed({ "SECRET" }) 
     @Produces(MediaType.TEXT_PLAIN) 
     public String itsSecret() { 
      return "secret"; 
     } 

    } 

JAXRSConfiguration.java:

import javax.ws.rs.ApplicationPath; 
    import javax.ws.rs.core.Application; 

    @ApplicationPath("resources") 
    public class JAXRSConfiguration extends Application { 

    } 

的web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
     version="3.1"> 
     <session-config> 
      <session-timeout>30</session-timeout> 
     </session-config> 
     <security-constraint> 
      <web-resource-collection> 
       <web-resource-name>Basic Authorization</web-resource-name> 
       <description/> 
       <url-pattern>/resources/*</url-pattern> 
      </web-resource-collection> 
      <auth-constraint> 
       <role-name>SECRET</role-name> 
      </auth-constraint> 
     </security-constraint> 
     <login-config> 
      <auth-method>BASIC</auth-method> 
      <realm-name>file</realm-name> 
     </login-config> 
     <error-page> 
      <exception-type>java.lang.Throwable</exception-type> 
      <location>/error/internal</location> 
     </error-page> 
     <security-role> 
      <role-name>SECRET</role-name> 
     </security-role> 
    </web-app> 

與GlassFish的web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> 
    <glassfish-web-app error-url=""> 
     <class-loader delegate="true"/> 
     <security-role-mapping> 
      <role-name>SECRET</role-name> 
      <group-name>cia</group-name> 
     </security-role-mapping> 
     <jsp-config> 
      <property name="keepgenerated" value="true"> 
       <description>Keep a copy of the generated servlet class' java code.</description> 
      </property> 
     </jsp-config> 
    </glassfish-web-app> 

的beans.xml:

<?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
    bean-discovery-mode="all"> 
    </beans> 

回答

1

在它的面前,這不是一個問題新澤西州。您配置的唯一真正的安全性是在servlet容器級別。你的澤西安全標註沒有任何影響,因爲你甚至沒有配置澤西特定的支持。

首先看你的web.xml配置

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>Basic Authorization</web-resource-name> 
     <description/> 
     <url-pattern>/resources/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>SECRET</role-name> 
    </auth-constraint> 
</security-constraint> 

第一部分設置是資源需要驗證。所以你認爲是一個@PermitAll不起作用的問題,實際上是由於你配置了servlet而不讓任何人通過認證的事實。

然後你設置的授權在servlet容器級別只允許與SECRET角色的用戶。因此,您的所有安全配置都在web.xml中配置。與澤西無關。

您需要了解解決此問題的另一件事,是認證與授權之間的區別,以及誰在扮演着什麼角色(與問候到servlet容器和澤西)。

@PermitAll,@RolesAllowed等只是澤西島處理授權的方式。預計已經有一個經過認證的用戶。澤西如何檢查這一點是通過從servlet請求中獲取委託人。如果沒有委託人,則假定沒有經過認證的用戶,並且不會允許任何人通過,即使您有@PermitAll,因爲即使@PermitAll要求用戶進行認證。

這就是說,我不知道是否有辦法在您的服務器中設置一個匿名用戶。這是得到你想要的行爲所需要的。請記住,澤西仍然要求有一個經過驗證的用戶。所以除非你能以某種方式在容器上設置一個匿名用戶,否則我不認爲你可以完成這項工作。

如果您對於安全和不安全的路徑有所不同,那麼您可以在web.xml中配置受保護的路徑,其他任何事情都會放開。有了這個,甚至不需要@PermitAll。請記住,使用@PermitAll時,它需要經過身份驗證的用戶。但是如果你只是刪除@PermitAll,那麼所有的請求都會通過。如果你分開安全和不安全之間的路徑,這將是可能的。

如果你想更好地控制所有這些,你可能會更好地實現自己的安全性,而不是使用servlet容器。通常我不會推薦這個,但基本認證可能是最簡單的安全協議。您可以查看this example,其中所有內容均使用澤西島過濾器完成。

最後要注意的是,你甚至沒有配置Jersey的授權支持。您仍然需要在應用程序中註冊RolesAllowedDynamicFeature。由於您正在爲JAX-RS配置使用類路徑掃描(空應用程序類),因此您需要從Feature註冊它,如this post

+0

中提到的那樣感謝您提供非常詳盡的答案。非常感激。 是的,將SecretResource和PublicResource放在不同的路徑中。這是我嘗試的第一件事,即帶有受保護訪問權限的「localhost:8080/resouces/secret/*」和匿名/公共訪問權限的「localhost:8080/resources/public/*」。混淆資源絆倒了我,讓他們都在相同的基本路徑中,事實上許可證似乎在我之前的項目中以不同的方式工作。無論如何,感謝指針。 – FighterHayabusa