如何让@RolesAllowed注释适用于我的Web应用程序?

时间:2014-09-15 15:16:40

标签: java security ejb jax-rs resteasy

我正在使用Backbone.js,Bootstrap,NetBeans IDE 8.0,Java EE 7,JDK 8,WildFly服务器8.1.0,JBoss RESTEasy(resteasy-jaxrs-3.0.8),JBoss 2.2.22制作Web应用程序, JBoss EJB 3。

我(相对)是Web开发的新手,因此我刚开始掌握了很多基本概念和技术。我正在尝试将用户和角色的权限系统构建到Web应用程序中,但我似乎无法使 @RolesAllowed注释在我的RESTful Web服务中工作。我已经在这个问题上工作了几天。

我有一个名为 UserResource.java 的RESTful资源(Java Enterprise / Session Bean?),在这里我有一个方法 create 来为应用程序创建一个新用户:

import java.net.URI;
import java.security.Principal;
import java.util.List;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import org.jboss.ejb3.annotation.SecurityDomain;

@Stateless
@SecurityDomain("other")
@Path("/user")
public class UserResource {
    @EJB(name = "UserServiceImp")
    UserService userService;

    @Context
    private UriInfo uriInfo;

    @RolesAllowed({"admin"})
    @Path("create")
    @POST
    public Response create(CreateRequest request) {        
        try {
            System.out.println("Start of create method");
            User user = userService.createUser(request);
            return getCreateResponse(user);
        }
        catch (Exception e){
            return Response.status(401).entity("Failed to create user").build();
        }
    }
}

如果我使用@PermitAll注释,则此 create 方法有效,但如果我使用@RolesAllowed注释,则会失败并显示错误。

我有这个Backbone视图 CreateUserView ,它为最终用户(具有管理员权限)提供表单(以HTML格式),用于为应用程序创建新用户。点击提交按钮后,JSON数据将被发送到网址< rest / user / create'用于创建新用户。在执行 UserResource.java 中的 create 方法之前,我的 SecurityInterceptor.java (实现 javax.ws.rs.container。 ContainerRequestFilter )检查用户是否具有所需权限。我已经彻底调试了这个,安全拦截器正在按预期运行。因此,在安全拦截器提供明确访问权限后, UserResource.java 中出现问题。 (作为旁注,不确定这是否重要,但我相信安全拦截器基于this blog post about RESTEasy security。我正在与另一个人一起工作,他最初实现了它,所以我不是当然..但它看起来几乎完全相同。无论如何,那个人几个星期前已经转移到另一个项目。)

我得到的错误(从服务器输出)如下:

16:45:25,775 ERROR [org.jboss.as.ejb3.invocation] (default task-60) JBAS014134: EJB Invocation failed on component UserResource for method public javax.ws.rs.core.Response org.profit.pgb.rest.resource.UserResource.create(org.profit.pgb.rest.api.CreateRequest): javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public javax.ws.rs.core.Response org.profit.pgb.rest.resource.UserResource.create(org.profit.pgb.rest.api.CreateRequest) of bean: UserResource is not allowed
    at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:135) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:95) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:64)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
    at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:448)
    at org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:61)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:326)
    at org.jboss.invocation.PrivilegedWithCombinerInterceptor.processInvocation(PrivilegedWithCombinerInterceptor.java:80)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:185)
    at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:182)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:73)
    at org.profit.pgb.rest.resource.UserResource$$$view45.create(Unknown Source) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_11]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_11]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_11]
    at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0_11]
    at org.jboss.weld.util.reflection.Reflections.invokeAndUnwrap(Reflections.java:401) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.EnterpriseBeanProxyMethodHandler.invoke(EnterpriseBeanProxyMethodHandler.java:99) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.EnterpriseTargetBeanInstance.invoke(EnterpriseTargetBeanInstance.java:56) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.InjectionPointPropagatingEnterpriseTargetBeanInstance.invoke(InjectionPointPropagatingEnterpriseTargetBeanInstance.java:65) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100) [weld-core-impl-2.1.2.Final.jar:2014-01-09 09:23]
    at org.profit.pgb.rest.resource.UserResource$Proxy$_$$_Weld$EnterpriseProxy$.create(Unknown Source) [classes:]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_11]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_11]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_11]
    at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0_11]
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) [resteasy-jaxrs-3.0.8.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_11]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_11]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_11]

16:45:25,957 ERROR [io.undertow.request] (default task-60) UT005023: Exception handling request to /pgb/rest/user/create: org.jboss.resteasy.spi.UnhandledException: javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public javax.ws.rs.core.Response org.profit.pgb.rest.resource.UserResource.create(org.profit.pgb.rest.api.CreateRequest) of bean: UserResource is not allowed
    at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:149) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:372) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.8.Final.jar:]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) [resteasy-jaxrs-3.0.8.Final.jar:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final]
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:177) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727) [undertow-core-1.0.15.Final.jar:1.0.15.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_11]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_11]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_11]
Caused by: javax.ejb.EJBAccessException: JBAS014502: Invocation on method: public javax.ws.rs.core.Response org.profit.pgb.rest.resource.UserResource.create(org.profit.pgb.rest.api.CreateRequest) of bean: UserResource is not allowed
    at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:135) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:95) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [wildfly-ejb3-8.1.0.Final.jar:8.1.0.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:309)
    at ... etc. (not fully shown due to SO's character limit on questions..)

我已经看到其他人提出类似的问题,有些问题至今尚未得到答复(例如jax-rs service RolesAllowed Annotation throwing exception)以及其他一些解决方案对我不起作用或者我可能不会应用解决方案的问题正确的(例如RESTEasy support for JAX-RS @RolesAllowed)。

我发现了这个:https://developer.jboss.org/thread/177728?start=0&tstart=0(标题为:" @RolesAllowed,@ DenyAll需要存在org.jboss.ejb3.annotation.SecurityDomain?" ),在尝试解决方案但我不能让它为我的项目工作。不确定解决方案是否适用于我的情况,或者我是否做错了。

我发现了这个:https://developer.jboss.org/message/720815(标题为:"这是处理org.jboss.ejb3.annotation.SecurityDomain的缺陷吗?" ),但我不明白我的 jboss-ejb-client.properties 应该在哪里。我认为他们的项目与我完全不同。所以没有运气。

我找到a guide on EJB3 security,正如那里建议的那样,我在 standalone.xml -file中提供了以下代码:

<security-domain name="other" cache-type="default">
    <authentication>
        <login-module code="Remoting" flag="optional">
            <module-option name="password-stacking" value="useFirstPass"/>
        </login-module>
        <login-module code="RealmDirect" flag="required">
            <module-option name="password-stacking" value="useFirstPass"/>
        </login-module>
    </authentication>
</security-domain>

但这根本没有解决任何问题。我不确定它是否做了什么。

最后,我发现了这个问题:RESTEasy support for JAX-RS @RolesAllowed(引用RESTEasy Documentation)。即使我也提到这个问题,但有几个段落包含一个对我不起作用的解决方案,它确实将错误更改为另一个错误。正如我所建议的那样,我在 web.xml -file中添加了&lt; context-param&gt; -block:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>PGB</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>

        <user-data-constraint>
            <!-- use of SSL is required when CONFIDENTIAL is specified -->
            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <context-param>
      <param-name>resteasy.role.based.security</param-name>
      <param-value>true</param-value>
   </context-param>
</web-app>

如果我尝试创建新用户,则会导致以下错误(由于SO问题的字符限制,此处未完全发布):

16:58:45,992 WARN  [org.jboss.resteasy.core.ExceptionHandler] (default task-61) failed to execute: javax.ws.rs.ForbiddenException: HTTP 403 Forbidden
    at org.jboss.resteasy.plugins.interceptors.RoleBasedSecurityFilter.filter(RoleBasedSecurityFilter.java:45) [resteasy-jaxrs-3.0.8.Final.jar:]
    at ... etc.

这个错误也不是很有帮助,事实上,当我搜索该错误时,我发现的信息比搜索上一个错误时更少。所以,我不确定这是否是迈向正确方向的一步。从服务器返回什么更好?状态500(内部服务器错误)或状态403(禁止)?此外,如果在应用了&#34;解决方案&#34;我将注释更改为@PermitAll,然后创建新用户就像以前一样工作,所以它并没有真正使情况变得更糟。

但是,我可以找到the source code of RoleBasedSecurityFilter,这表明它会抛出ForbiddenException。它表明某个 isUserInRole 方法必须返回true,但它在我的应用程序中不会这样做。我无法让它返回真实。这让我很奇怪,Is it possible to disable RoleBasedSecurityFilter.java of RESTEasy?

我还发现了以下SO问题:@RolesAllowed cannot be resolved with Jersey,由Abhijit Sarkar回答,他提到an IBM article。也许我的问题的解决方案在那里,但我还没有找到它..无论如何,建议在那里添加 security-role 块到我的 web.xml -file或在我的 UserResource.java 文件中添加 @DeclareRoles 注释应该可以解决问题,但是在我这样做之后仍然会保留HTTP 403 Forbidden警告。这非常令人沮丧。

我的 security-role 块(在web.xml中)如下所示:

<security-role id="role_admin">
    <description>This is role 1 (admin)</description>
    <role-name>admin</role-name>
</security-role>

我添加了以下 security-constraint 块(在web.xml中):(注意 auth-constraint

<security-constraint>
    <web-resource-collection>
        <web-resource-name>PGB</web-resource-name>
        <url-pattern>/rest/user/create</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint id="AuthConstraint_createUser">
        <description> Only admin can create a new user</description>
        <role-name>admin</role-name>
    </auth-constraint>
    <user-data-constraint>
        <!-- use of SSL is required when CONFIDENTIAL is specified -->
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

我现在意识到我的问题出在部署描述符( web.xml )或服务器配置(WildFly&#39; s standalone-full.xml

我在 web.xml 文件中添加了login-config元素(带有FORM authentication)。将我的登录HTML页面更改为适合the required format。我在migrating a Java EE App from GlassFish to WildFly上执行了本文的一些步骤,但我认为我仍然做错了,因为我在尝试使用有效的用户凭据登录时总是进入登录错误页面。

请在此处查看我添加到WildFly配置中的security-domain元素:

<security-domain name="app" cache-type="default">
    <authentication>
        <login-module code="Database" flag="required">
            <module-option name="dsJndiName" value="java:jboss/datasources/mySQL_pool_rel"/>
            <module-option name="principalsQuery" value="select hashed_password from user where email_address=?"/>
            <module-option name="rolesQuery" value="select role_name, 'Roles' from role r inner join user u on r.role_type = u.role_type where u.email_address = ?"/>
            <module-option name="hashAlgorithm" value="SHA-256"/>
            <module-option name="hashEncoding" value="BASE64"/>
            <module-option name="unauthenticatedIdentity" value="guest"/>
        </login-module>
        <login-module code="RoleMapping" flag="required">
             <module-option name="rolesProperties" value="file:${jboss.server.config.dir}/app.properties"/>
             <module-option name="replaceRole" value="false"/>
        </login-module>
    </authentication>
</security-domain>

我认为那里定义的 rolesQuery 出了问题,但我无法弄清楚是什么。

我很想知道如何为我的Web应用程序实现基于角色的安全性。因此,我也接受其他基于角色的安全方法,只要它有效。欢迎提出建议。

我也放了my question on developer.jboss.org,但我还没有回复。

我为我的问题提供了一个解决方案作为这个问题的答案,但它不是一个真正的解决方案(如该答案所述)。我仍然有兴趣以正确的方式这样做。

4 个答案:

答案 0 :(得分:8)

刚遇到同样的问题。

这是@Stateless注释。将您的类标记为EJB,容器尝试强制实施EJB安全性。

我通过编写过滤器和我自己的SecurityContext来发现这一点,但却发现我的SecurityContext从未被引用过。

删除@Stateless导致在getUserPrincipal()上调用SecurityContext

答案 1 :(得分:4)

基于错误&#34; 403&#34;,在我看来,您的角色查询有问题。也许,您的登录模块没有分配&#34; admin&#34;角色给你的用户。您可以做的一件事是实现自定义身份验证机制http://undertow.io/undertow-docs/undertow-docs-1.3.0/#authentication-mechanisms(例如:https://github.com/dstraub/spnego-wildfly),并以这样一种方式对其进行修改,以便您可以检查登录模块分配给用户的角色。实现自定义身份验证机制需要花费一些时间,但它可以帮助您更好地了解wildfly中的安全性。

我必须做的其他事情才能使我的角色注释工作是修改standalone.xml并将您的安全域设置为默认域。

另外,对我来说,添加这些线条是朝着正确方向迈出的一步。如果没有那些注释,@ RolesAllowed就不适合我。

<context-param>
    <param-name>resteasy.role.based.security</param-name>
    <param-value>true</param-value>
</context-param>

另外,我建议仅使用web.xml实现安全性,只有在完成之后,才尝试添加@RolesAllowed。

答案 2 :(得分:1)

我找到了解决问题的方法。但是,这不是问题的解决方案,因为它不是workaround,因为它不使用 @RolesAllowed 注释。

由于我无法弄清楚如何准确定义我的部署描述符和服务器配置,我认为如果我只是不使用 @RolesAllowed 注释,问题就会更容易解决。

尽管其他人可能真的想在 web.xml 文件中使用login-config元素而不使用任何其他身份验证方法,但这种方法并不使用该元素,而是仅通过RESTful Web Services进行身份验证(这意味着在部署描述符或服务器配置中不需要更改任何内容)。

我创建了一个名为SecurityFilter的新 Enterprise Java Bean(EJB),用于检查用户是否具有某些功能所需的角色。它实现如下:

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.core.HttpHeaders;
import org.profit.pgb.rest.user.UserService;

@Stateless
public class SecurityFilter
{
    @EJB(name = "UserServiceImp")
    UserService userService;

    public boolean isUserAllowed (String[] rolesArray, HttpHeaders hHeaders)
    {
        Set<String> rolesSet = new HashSet<>(Arrays.asList(rolesArray));

        String uuid = hHeaders.getRequestHeader("user").get(0);
        String token = hHeaders.getRequestHeader("token").get(0);

        if (userService.isAuthorizationTokenValid(uuid, token))
        {
           if (userService.isUserAllowed(uuid, rolesSet))
           {
               return true; // user allowed access
           }
        }   
        return false; // 401
    }
}

UserResource.java create 方法中调用 isUserAllowed 方法。在上面的问题中可以看到此 create 方法的旧实现。新的实施如下:

@PermitAll
@Path("create")
@POST
public Response create(CreateRequest request, @Context HttpHeaders hHeaders) {  
    if (securityFilter.isUserAllowed(new String[]{"admin"}, hHeaders))
    {
        try {
            System.out.println("Start of create method");
            User user = userService.createUser(request);
            return getCreateResponse(user);
        }
        catch (Exception e){
            return Response.status(401).entity("Failed to create user").build();
        }
    }
    else
        return Response.status(401).entity("Access denied! User does not have permission to create user").build();
}

正如您所看到的,if-else语句替换了此方法中的 @RolesAllowed 注释,我的安全过滤器实现略有不同。

此外,此方法使用HttpHeaders来获取请求标头(其中存储了用户标识和标记)。 The accepted answer关于SO问题&#34; how to received "Accept" header in REST web service server side&#34;帮我找到how to get the request headers

此外,这种方法无需更改我的 Backbone.js - 和 Bootstrap 网页(即我的HTML和JavaScript文件)中的任何内容。

答案 3 :(得分:0)

我在答案here上看到了你的帖子。我对JBoss专有安全性不太熟悉,我也不建议将它嵌入代码中,但我想这不是我的问题。从您的代码中,我看不到security-role@DeclareRoles;在我的回答中清楚地提到,你需要一个基于注释的安全性才能工作。你为了简洁而排除了它,或者你错过了吗?如果是后者,请将@DeclareRoles添加到UserResource课程,看看是否有帮助。