我正在使用JAX-RS使用泽西实施。我正在尝试使用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
请告诉我如何解决此问题?这需要特定的罐子/ 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>
请让我知道这个问题。
答案 0 :(得分:11)
我在this的一行文章开启了我的眼睛之前,我在类似的问题上挣扎了好几个小时。令人惊讶的是,没有一本书或用户指南提到这个关键事实,没有它,认证就无法成功。
使用基于注释的安全性时, web.xml不是可选的;恰恰相反,必须存在<security-constraint>
元素; Web容器在JAX-RS执行之前检查安全性,如果没有<security-constraint>
,则不会设置正确的安全上下文。因此,当JAX-RS调用isUserInRole(role)
时,它总是返回false。
此外,web.xml中的<security-role>
个元素或@DeclareRoles
注释必须存在。
最后,如果使用Jersey,则需要在Application类中注册RolesAllowedDynamicFeature
以启用基于注释的安全性。
答案 1 :(得分:3)
你的代码中有导入吗?
import javax.annotation.security.RolesAllowed;
还要确保{class 1}}在您的类路径中。 jar可以在Tomcat安装lib文件夹中找到。
答案 2 :(得分: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>
安全注释不适用于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>
注意:以下代码特定于Jersey。
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);
}
}
确保您在步骤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>
在下面的示例中,我们尝试保护对/ test / *的访问。您没有指定任何HTTP方法,这一点非常重要。 (例如<http-method>GET</http-method>
)这意味着您拒绝访问所有HTTP方法。
但是,您需要通过<auth-constraint>
元素定义可以访问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>
以下示例说明了BASIC身份验证。
<web-app …>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>test</realm-name>
</login-config>
</web-app>
安全角色应该与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>
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>
答案 3 :(得分:0)
我不知道任何声明@RolesAllows的java库。 Java6 EE API docs仅声明安全使用的5个注释。
@DeclareRoles
@DenyAll
@PermitAll
@RolesAllowed
@RunAs
如果你试图覆盖类角色,你不能简单地将@RolesAllowed
放在你的方法中,就像你一样,我相信它会起作用。
答案 4 :(得分:0)
我认为你应该添加jsr250-api-1.0.jar。如果您使用Maven,可以添加:
<dependency>
<!-- Annotations for role management -->
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>