Pregunta ¿Cómo puedo obtener la anotación @RolesAllowed para que funcione en mi aplicación web?


Estoy haciendo una aplicación web usando Backbone.js, Bootstrap, NetBeans IDE 8.0, Java EE 7, JDK 8, servidor WildFly 8.1.0, JBoss RESTEasy (resteasy-jaxrs-3.0.8), JBoss 2.2.22, JBoss EJB 3 .

Soy (relativamente) nuevo en el desarrollo web y, como tal, acabo de comenzar a comprender una gran cantidad de conceptos y tecnologías básicos. Estoy intentando construir un sistema de permisos con usuarios y roles en una aplicación web, pero parece que no puedo @RolesAllowed anotación para trabajar en mi servicio web RESTful. Ya estoy trabajando en este problema por unos días.

Tengo un recurso RESTful (Java Enterprise / Session Bean?) Llamado UserResource.java, aquí tengo un método crear para crear un nuevo usuario para la aplicación:

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();
        }
    }
}

Esta crear El método funciona si utilizo la anotación @PermitAll, pero falla con un error si uso la anotación @RolesAllowed.

Tengo esta vista Backbone CreateUserView que proporciona un formulario (en HTML) a un usuario final (con derechos de administrador) para crear nuevos usuarios para la aplicación. Al hacer clic en el botón Enviar, los datos JSON se envían a la url 'reposo / usuario / crear' para crear un nuevo usuario. Antes de crear método en UserResource.java se ejecuta, mi SecurityInterceptor.java (que implementa javax.ws.rs.container.ContainerRequestFilter) comprueba si el usuario tiene los permisos necesarios. He depurado esto a fondo y el interceptor de seguridad está funcionando como debería. Entonces, después de que el interceptor de seguridad da acceso claro, algo sale mal en UserResource.java. (Como nota al margen, no estoy seguro de si esto es importante, pero creo que el interceptor de seguridad se basa en esta publicación de blog sobre RESTEasequilidad de seguridad. Estuve trabajando en la aplicación con otro chico, inicialmente lo implementó, así que no estoy seguro ... pero parece casi idéntico. De todos modos, ese tipo se mudó a otro proyecto hace unas semanas).

El error que estoy obteniendo (salida del servidor) es el siguiente:

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..)

He visto a otras personas hacer preguntas similares, algunas de las cuales permanecen sin respuesta hasta el día de hoy (p. Servicio jax-rs RolesAllowed Anotación lanzando excepción) y otros que tienen soluciones que no me funcionan o que quizás no apliquen la solución correctamente (p. Soporte RESTE fácil para JAX-RS @RolesAllowed)

Encontré esto: https://developer.jboss.org/thread/177728?start=0&tstart=0 (noble: "@RolesAllowed, @DenyAll requieren presencia de org.jboss.ejb3.annotation.SecurityDomain?"), Intenté la solución pero no puedo hacer que funcione para mi proyecto. No estoy seguro si la solución no es aplicable para mi situación o si solo lo estoy haciendo mal.

Encontré esto: https://developer.jboss.org/message/720815 (noble: "¿Es esto un defecto para procesar org.jboss.ejb3.annotation.SecurityDomain?"), pero no entiendo dónde está mi jboss-ejb-client.properties se supone que es. Creo que establecieron su proyecto bastante diferente de mí. Entonces no hay suerte con eso.

encontré una guía sobre la seguridad de EJB3, como se sugirió allí, proporcioné el siguiente código en mi standalone.xml-archivo:

<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>

Pero eso no solucionó nada en absoluto. No estoy seguro si hizo algo.

Finalmente, encontré esta pregunta SO: Soporte RESTE fácil para JAX-RS @RolesAllowed (qué referencias al Documentación RESTEasy) Aunque también mencioné esta pregunta algunos párrafos como que contiene una solución que no funciona para mí, sí cambió el error a otro error. Como se sugirió allí, agregué un <context-param>-bloquear a mi web.xml-archivo:

<?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>

Lo que resulta en el siguiente error si intento crear un nuevo usuario (no publicado por completo aquí debido al límite de caracteres de las preguntas 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.

Este error tampoco es muy útil, de hecho, encuentro aún menos información cuando busco ese error que cuando busco el error anterior. Entonces, no estoy seguro si eso es un paso en la dirección correcta. ¿Qué es mejor haber regresado del servidor? ¿Un estado 500 (Internal Server Error) o un estado 403 (Forbidden)? Además, si después de aplicar esa "solución" cambio la anotación a @PermitAll, entonces la creación de un nuevo usuario funciona igual que antes, por lo que realmente no empeoró la situación.

Sin embargo, puedo encontrar el código fuente de RoleBasedSecurityFilter, que muestra que arroja el ForbiddenException. Muestra que un cierto isUserInRole El método debe ser verdadero, pero no funciona en mi aplicación. No puedo hacer que vuelva verdadero. Me hace pensar, ¿Es posible deshabilitar RoleBasedSecurityFilter.java de RESTEasy?

También encontré la siguiente pregunta SO: @RolesAllowed no se puede resolver con Jersey, que es respondida por Abhijit Sarkar, y se refiere a un artículo de IBM. Tal vez la solución a mi problema esté ahí, pero todavía no lo he encontrado ... De todos modos, se sugiere que agregue un rol de seguridad bloquear a mi web.xml-archivo o agregando un @DeclareRoles anotación a mi UserResource.java archivo debería resolver el problema, pero la advertencia de HTTP 403 Prohibido aún permanece después de que lo haga. Es muy frustrante

Mi rol de seguridad block (en web.xml) se ve de la siguiente manera:

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

Y agregué lo siguiente restricción de seguridad bloque (en web.xml): (tenga en cuenta 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>

Ahora me doy cuenta de que mi problema radica en los descriptores de implementación (web.xml) o la configuración del servidor (WildFly's standalone-full.xml)

Agregué un login-config elemento (con Autenticación FORM) para mi web.xml archivo. Cambié mi página de inicio de sesión de HTML para que se ajuste el formato requerido. Seguí algunos de los pasos de este artículo sobre migrar una aplicación Java EE de GlassFish a WildFly, pero creo que todavía hice algo mal porque siempre llego a la página de error de inicio de sesión cuando intento iniciar sesión con credenciales de usuario válidas.

Vea aquí el security-domain elemento que agregué a mi configuración de WildFly:

<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>

Creo que algo está mal con mi rolesQuery definido allí, pero no puedo entender qué.

Me encantaría saber cómo implementar la seguridad basada en roles para mi aplicación web. Por lo tanto, también acepto otros enfoques para la seguridad basada en roles, siempre y cuando funcione. Sugerencias son bienvenidas.

Yo también coloqué mi pregunta en developer.jboss.org, pero tampoco recibí respuesta todavía.

Proporcioné una solución alternativa a mi problema como respuesta a esta pregunta, pero no es una solución real (como se explica en esa respuesta). Todavía estoy interesado en hacer esto de la manera correcta.


14
2017-09-15 15:16


origen


Respuestas:


Solo tuve el mismo problema.

Es el @Stateless anotación. Marca su clase como un EJB y el contenedor intenta aplicar la seguridad de EJB.

Descubrí esto al escribir filtros y mi propio SecurityContext, solo para encontrar que mi SecurityContext nunca fue referenciado

Eliminando @Stateless resultó en getUserPrincipal() siendo llamado en el SecurityContext.


7
2017-09-22 08:19



Basado en el error "403", me parece que hay algo mal con su consulta de función. Tal vez, su módulo de inicio de sesión no asigne el rol de "administrador" a su usuario. Una cosa que podrías hacer es implementar un mecanismo de autenticación personalizado http://undertow.io/undertow-docs/undertow-docs-1.3.0/#authentication-mechanisms (ejemplo: https://github.com/dstraub/spnego-wildfly), y modifíquelo de tal forma que pueda verificar qué funciones asigna su módulo de inicio de sesión a su usuario. Implementar un mecanismo de autenticación personalizado le llevará algo de tiempo, pero le ayuda a comprender mejor cómo funciona la seguridad en wildfly.

Otra cosa que tuve que hacer para que mi anotación de Roles funcione es modificar standalone.xml y establecer su dominio de seguridad como el predeterminado.

Además, agregar esas líneas es un paso en la dirección correcta, en cuanto a mí. Sin esas líneas, las anotaciones @RolesAllowed no funcionan para mí.

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

Además, recomendaría la implementación de seguridad utilizando solo web.xml, y solo después de eso, intente agregar @RolesAllowed.


4
2017-12-19 12:59



Encontré una solución a mi problema. Sin embargo, esto no es tanto una solución al problema, ya que es una workaround, porque no usa el @RolesAllowed anotación.

Como no pude encontrar la manera exacta de definir mis descriptores de implementación y la configuración del servidor, pensé que el problema se resolvería mucho más fácilmente si simplemente no usara el @RolesAllowed anotación.

Aunque otras personas realmente quieran usar el login-config elemento en su web.xml archivo y no use ningún otro medio de autenticación, este enfoque no utiliza ese elemento sino que realiza la autenticación únicamente a través de Servicios web RESTful (lo que significa que no es necesario cambiar nada en los descriptores de implementación o la configuración del servidor).

Creé un nuevo Enterprise Java Bean (EJB) llamado SecurityFilter que verifica si un usuario tiene los roles requeridos para ciertas funcionalidades. Se implementa de la siguiente manera:

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
    }
}

El método isUserAllowed se llama en el crear método de UserResource.java. La vieja implementación de esto crear método se puede ver en la pregunta anterior. La nueva implementación es la siguiente:

@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();
}

Como puede ver, una instrucción if-else reemplaza el @RolesAllowed anotación en este enfoque y mi filtro de seguridad se implementa ligeramente diferente.

Además, este enfoque utiliza HttpHeaders para obtener los encabezados de solicitud (en los que se almacenan la identificación de usuario y el token). La respuesta aceptada en la pregunta SO "cómo recibir el encabezado "Aceptar" en el lado del servidor del servicio web REST"me ayudó a encontrar cómo obtener los encabezados de las solicitudes.

Además, este enfoque funciona sin cambiar nada en mi Backbone.js- y Orejabasadas en páginas web (es decir, mis archivos HTML y JavaScript).


1
2017-09-26 12:41



Vi tu publicación en mi respuesta aquí. No estoy muy familiarizado con la seguridad de propiedad de JBoss, tampoco recomiendo tenerlo incrustado en el código, pero supongo que ese no es mi problema. De tu código, no veo security-role o @DeclareRoles presente; En mi respuesta se menciona claramente que necesita uno para que funcione la seguridad basada en anotaciones. ¿Lo excluyeste por brevedad o lo perdiste? En el caso de lo último, agregue @DeclareRoles a UserResource clase y ver si eso ayuda.


0
2017-09-21 10:04