【问题标题】:@RolesAllowed cannot be resolved with Jersey@RolesAllowed 无法用 Jersey 解决
【发布时间】:2013-03-03 18:06:26
【问题描述】:

我正在使用 JAX-RS 和 jersey 实现。我正在尝试使用 Tomcat 6 使用 BASIC 身份验证来验证我的服务。

这是代码:

@Path("/authenticate")
@RolesAllowed({"Admin","Guest"})
public class BasicAuthenticationSecurity {

@GET
@Path("/wbiPing")
@Produces(MediaType.TEXT_PLAIN) 
@RolesAllowed("Admin")
public Response wbiPing(){

System.out.println("Pinged!!!");
return Response.ok("Pinged!!!").build();
}

}

当我尝试使用 @RolesAllows 注释我的方法时,我收到编译错误:

@RolesAllows cannot be resolved to a type

请告诉我如何解决这个问题?为此需要任何特定的 jars/API?

编辑:

web.xml

<servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>
            com.security;
            com.exception
        </param-value>
    </init-param>       
    <init-param>
        <param-name>com.sun.jersey.spi.container.ResourceFilters</param-name>
        <param-value>com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<security-constraint>      
  <web-resource-collection>
      <web-resource-name>BasicDemo</web-resource-name>          
      <url-pattern>/*</url-pattern>
      <http-method>GET</http-method>
  </web-resource-collection>
  <auth-constraint>
      <role-name>Admin</role-name>
  </auth-constraint>
</security-constraint>
  <login-config>
  <auth-method>BASIC</auth-method>
  <!-- The realm name is typically displayed by the browser in the login dialog box. -->
  <realm-name>Login</realm-name>      
  </login-config>

请让我知道这个问题。

【问题讨论】:

    标签: java web-services rest jersey jax-rs


    【解决方案1】:

    this IBM 文章中的一行让我大开眼界之前,我为类似的问题苦苦挣扎了好几个小时。令人惊讶的是,没有一本书或用户指南提到这一关键事实,否则身份验证将无法成功。

    使用基于注释的安全性时,web.xml 不是可选的;恰恰相反,&lt;security-constraint&gt; 元素必须存在; Web 容器在 JAX-RS 之前检查安全性,如果没有 &lt;security-constraint&gt;,则未设置正确的安全上下文。因此,当 JAX-RS 调用 isUserInRole(role) 时,它总是返回 false。

    此外,web.xml 中的&lt;security-role&gt; 元素或@DeclareRoles 注释必须存在。

    最后,如果使用 Jersey,RolesAllowedDynamicFeature 需要在 Application 类中注册以启用基于注释的安全性。

    HTH 其他与可怜的文档作斗争或缺乏文档的人,就在那里。

    【讨论】:

    • 你好@Abhijit Sarkar,我不知道你是否会回到 SO,但我有一个与你提出这个答案的问题类似的问题。你可以在这里找到它:stackoverflow.com/questions/25851374/… 我不知道有什么其他方式可以联系你,因为你没有在你的个人资料中提供联系方式,而且你的名字在谷歌上搜索时很常见。无论如何,如果您能帮我解决我的问题,我将不胜感激。
    【解决方案2】:

    您的代码中有导入吗?

    import javax.annotation.security.RolesAllowed;
    

    还要确保annotations-api.jar 在您的类路径中。 jar 可以在 Tomcat 安装 lib 文件夹中找到。

    【讨论】:

    • 感谢您的回复,我尝试了您的建议。我在 ExceptionMapper 中遇到异常:com.sun.jersey.api.NotFoundException: null for uri: http://localhost:8002/BASICAuthentication/rest/authenticate/wbiPing 此异常是为有效用户引发的。对于无效用户,将显示 403 错误页面。请让我知道为什么有效用户会出现这种行为?我已经用我的最新代码更新了第一篇文章,请看一下。
    【解决方案3】:

    终于成功了!

    以下是使其在 Tomcat 和 Jersey 中工作的步骤。

    假设我们在 TOMCAT_HOME/conf/tomcat-users.xml 中有以下内容,我们在其中定义了 2 个角色 - 编辑者和成员。

    我们还定义了三个用户 - gavin、julie 和 admin。

    <?xml version="1.0" encoding="UTF-8"?>
      <role rolename="editor"/>
      <role rolename="member"/>
    
      <user username="admin" password="qwerty" roles="editor,member"/>
      <user username="gavin" password="qwerty" roles="editor"/>
      <user username="julie" password="qwerty" roles="member"/>
    </tomcat-users>
    

    步骤 1. 确保在 web.xml 中使用 Servlet 3.0 规范

    安全注释不适用于 Servlet 2.5 及更低版本。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
    
    </web-app>
    

    第 2 步。创建应用程序类以启用安全注释

    注意:以下代码特定于泽西岛。

    package ph.activelearning.rest.security;
    
    import org.glassfish.jersey.server.ResourceConfig;
    import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
    
    public class MyApplication extends ResourceConfig {
        public MyApplication() {
            super(TestResource.class);
            register(RolesAllowedDynamicFeature.class);
        }
    }
    

    步骤 3. 在 web.xml 中指定您的应用程序类

    确保您在第 2 步中创建的 Application 类被 Jersey 识别。

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>ph.activelearning.rest.security</param-value>
        </init-param>
    
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>ph.activelearning.rest.security.MyApplication</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    步骤 4. 在 web.xml 中创建安全约束

    讽刺的是,即使我们要使用安全注解,我们仍然需要在 web.xml 中定义一个安全约束。

    在下面的示例中,我们尝试保护对 /test/* 的访问。不要指定任何 HTTP 方法,这一点很重要。 (例如&lt;http-method&gt;GET&lt;/http-method&gt;)这意味着您拒绝访问所有 HTTP 方法。

    不过,您需要通过&lt;auth-constraint&gt; 元素定义所有可以访问URL 的角色,而不管使用何种方法。

    <web-app …>
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>test</web-resource-name>
                <url-pattern>/test/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>editor</role-name>
                <role-name>member</role-name>
            </auth-constraint>
        </security-constraint>
    </web-app>
    

    步骤 5. 在 web.xml 中指定认证方法

    以下示例说明了 BASIC 身份验证。

    <web-app …>
        <login-config>
            <auth-method>BASIC</auth-method>
            <realm-name>test</realm-name>
        </login-config>
    </web-app>
    

    第 6 步。定义安全角色

    安全角色应该对应于在 tomcat-users.xml 中定义的相同角色。在本例中,我们定义角色编辑者和成员。

    注意:这一步似乎是可选的,因为即使没有它,身份验证/授权仍然有效。

    <web-app ...>
        <security-role>
             <description>This is editor</description>
             <role-name>editor</role-name>
        </security-role>
    
         <security-role>
             <description>This is member</description>
             <role-name>member</role-name>
        </security-role>
    </web-app>
    

    第 7 步。注释您的资源

    package ph.activelearning.rest.security;
    
    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.Context;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.SecurityContext;
    
    @Path("test")
    @PermitAll
    public class TestResource {
    
        @GET
        @Path("editor")
        @Produces(MediaType.TEXT_PLAIN)
        @RolesAllowed("editor")
        public String editorOnly() {
            return "Got to editor path!";
        }
    
        @GET
        @Path("member")
        @Produces(MediaType.TEXT_PLAIN)
        @RolesAllowed("member")
        public String memberOnly() {
            return "Got to member path!";
        }
    
        @GET 
        @Path("open")
        @Produces(MediaType.TEXT_PLAIN)
        public String open(@Context SecurityContext context) {
            return "Open to all! - " + context.getUserPrincipal().getName();
        }
    }
    

    就是这样。这是完整的 web.xml,供您享受编程乐趣。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version="3.0">
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>jersey.config.server.provider.packages</param-name>
                <param-value>ph.activelearning.rest.security</param-value>
            </init-param>
    
            <!-- Define the Application class where we enable security annotations -->
            <init-param>
                <param-name>javax.ws.rs.Application</param-name>
                <param-value>ph.activelearning.rest.security.MyApplication</param-value>
            </init-param>
    
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    
        <!-- Required even though we use annotations -->
        <security-constraint>
            <web-resource-collection>
                <web-resource-name>test</web-resource-name>
                <url-pattern>/test/*</url-pattern>
            </web-resource-collection>
            <auth-constraint>
                <role-name>editor</role-name>
                <role-name>member</role-name>
            </auth-constraint>
        </security-constraint>
    
        <login-config>
            <auth-method>BASIC</auth-method>
            <realm-name>test</realm-name>
        </login-config>
    
        <!-- Optional: Define security roles that are defined in your app server -->
        <!--  
        <security-role>
            <description>This is editor</description>
            <role-name>editor</role-name>
        </security-role>
    
        <security-role>
            <description>This is member</description>
            <role-name>member</role-name>
        </security-role>
        -->
    
    </web-app>
    

    【讨论】:

      【解决方案4】:

      我不知道任何声明@RolesAllows 的Java 库。 Java6 EE API docs 仅声明 5 个注解以供安全使用。

      @DeclareRoles
      @DenyAll
      @PermitAll
      @RolesAllowed
      @RunAs
      

      如果您尝试覆盖类角色,您不能像您所做的那样简单地将@RolesAllowed 放入您的方法中,我相信这会起作用。

      【讨论】:

      • 感谢您的回复。我已经配置了 Tomcat 领域,修改了 web.xml 中的条目,如此链接中提到的:stackoverflow.com/questions/15158554/… 请提供您对此的输入,从过去几天开始一直在努力解决这个问题:(
      【解决方案5】:

      我认为您应该添加 jsr250-api-1.0.jar。如果你使用 Maven,你可以添加这个:

          <dependency>
              <!-- Annotations for role management -->
              <groupId>javax.annotation</groupId>
              <artifactId>jsr250-api</artifactId>
              <version>1.0</version>
          </dependency>
      

      【讨论】:

      • 我尝试了这个选项,但仍然是同样的问题:(关于此的任何进一步的帮助/想法?
      • 我认为 Deividi 是对的。它应该是“RolesAllowed”而不是“RolesAllows”。这是一个错字。
      猜你喜欢
      • 2019-01-19
      • 2017-06-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      相关资源
      最近更新 更多