我正在尝试根据我通过Jersey / JAX-RS公开的资源的角色设置身份验证。此资源存在于Glassfish实例中,其中基于角色的身份验证(特别是通过@RolesAllowed)当前正在按需运行。我在servlet容器中运行Jersey:
<servlet-class>
com.sun.jersey.spi.container.servlet.ServletContainer
</servlet-class>
我正在对我的资源强制执行基本身份验证;该要求正在按预期执行。我还为Jersey提供了以下初始化参数:
<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>
但是,当我尝试实际添加@RolesAllowed注释时,所有访问都会失败。例如:
@Path("/my/resource")
@ManagedBean
@RolesAllowed({"SYSTEM"})
public class Resource {
// Accesses with credentials for a user that has the SYSTEM role fail!
}
如果我注入安全上下文并调用context.isUserInRole(),则会为所有角色返回false。非常奇怪的是,如果我删除此资源的@RolesAllowed注释,并使用有效凭据发出请求,则此类可以成功访问EJB,这需要用户与我最初尝试测试的角色相同。似乎泽西可能正在使用错误的SecurityContext进行身份验证,或者其他一些。还有其他人经历过这个吗?
答案 0 :(得分:8)
我在this的一行文章开启了我的眼睛之前,我在类似的问题上挣扎了好几个小时。令人惊讶的是,没有一本书或用户指南提到这个关键事实,没有它,认证就无法成功。
使用基于注释的安全性时, web.xml不是可选的;恰恰相反,必须存在<security-constraint>
元素; Web容器在JAX-RS执行之前检查安全性,如果没有<security-constraint>
,则不会设置正确的安全上下文。因此,当JAX-RS调用isUserInRole(role)
时,它总是返回false。
此外,web.xml中的<security-role>
个元素或@DeclareRoles
注释必须存在。
最后,如果使用Jersey,则需要在Application类中注册RolesAllowedDynamicFeature
以启用基于注释的安全性。