web-dev-qa-db-fra.com

Comment faire en sorte que l'annotation @RolesAllowed fonctionne pour mon application Web?

Je réalise une application Web à l'aide de Backbone.js, Bootstrap, NetBeans IDE 8.0, Java EE 7, JDK 8, serveur WildFly 8.1.0, JBoss RESTEasy (resteasy-jaxrs-3.0.8), JBoss 2.2.22. , JBoss EJB 3.

Je suis (relativement) nouveau en développement Web et, à ce titre, je commence tout juste à comprendre un grand nombre de concepts et de technologies de base. J'essaie de créer un système de permissions avec des utilisateurs et des rôles dans une application Web, mais je n'arrive pas à faire en sorte que l'annotation @RolesAllowed fonctionne dans mon service Web RESTful. Je travaille déjà sur ce problème depuis quelques jours.

J'ai une ressource RESTful (Java Enterprise/Session Bean?) Appelée UserResource.Java, j'ai ici une méthode create pour créer un nouvel utilisateur pour l'application:

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

Cette méthode create fonctionne si j'utilise l'annotation @PermitAll, mais échoue avec une erreur si j'utilise l'annotation @RolesAllowed.

J'ai cette vue Backbone CreateUserView qui fournit un formulaire (en HTML) à un utilisateur final (avec des droits d'administrateur) pour créer de nouveaux utilisateurs pour l'application. En cliquant sur le bouton d'envoi, les données JSON sont envoyées à l'URL 'reste/utilisateur/créer' pour créer un nouvel utilisateur. Avant que la méthode create dans UserResource.Java soit exécutée, mon SecurityInterceptor.Java (qui implémente javax.ws.rs.container.ContainerRequestFilter) vérifie si l'utilisateur dispose de la autorisations requises. J'ai procédé à un débogage minutieux et l'intercepteur de sécurité fonctionne comme il se doit. Ainsi, après que l'intercepteur de sécurité donne un accès clair, quelque chose ne va pas dans UserResource.Java. (En passant, je ne sais pas si cela est important, mais je crois que Security Interceptor est basé sur ce billet de blog sur RESTEasy security . Je travaillais sur l’application avec un autre gars, il l’a initialement mis en œuvre. Je ne suis pas sûr… mais ça a l'air presque identique. Quoi qu'il en soit, ce gars est passé à un autre projet il y a quelques semaines.)

L'erreur que je reçois (sortie du serveur) est la suivante:

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

J'ai vu d'autres personnes poser des questions similaires, dont certaines restent sans réponse à ce jour (par exemple, service jax-rs RolesAllowed exception de projection ) et d'autres qui proposent des solutions qui ne fonctionnent pas pour moi ou peut-être que je ne les applique pas. correctement la solution (par exemple, prise en charge de RESTEasy pour JAX-RS @RolesAllowed ).

J'ai trouvé ceci: https://developer.jboss.org/thread/177728?start=0&tstart=0 (intitulé: "@RolesAllowed, @DenyAll nécessite la présence de org.jboss.ejb3.annotation.SecurityDomain ? "), J'ai essayé la solution mais je ne peux pas la faire fonctionner pour mon projet. Je ne sais pas si la solution ne convient pas à ma situation ou si je me trompe tout simplement.

J'ai trouvé ceci: https://developer.jboss.org/message/720815 (intitulé: "s'agit-il d'un défaut de traitement de org.jboss.ejb3.annotation.SecurityDomain?"), Mais je ne comprends pas où sont supposés être mes jboss-ejb-client.properties. Je pense qu'ils ont mis leur projet en place très différemment de moi. Donc pas de chance avec ça.

J'ai trouvé un guide sur la sécurité EJB3 , comme suggéré ici, j'ai fourni le code suivant dans mon fichier standalone.xml:

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

Mais cela n'a rien résolu du tout. Je ne suis pas sûr si cela a fait quelque chose.

Enfin, j'ai trouvé cette SO question: Prise en charge de RESTEasy pour JAX-RS @RolesAllowed (qui fait référence à la Documentation RESTEasy ). Même si j’ai aussi mentionné cette question quelques paragraphes plus haut comme contenant une solution qui ne fonctionne pas pour moi, cela a changé l’erreur en une autre erreur. Comme suggéré, j'ai ajouté un <context-param> -block à mon web.xml -file:

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

Ce qui entraîne l'erreur suivante si j'essaie de créer un nouvel utilisateur (non complètement posté ici en raison de la limite de caractères de SO questions):

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.

Cette erreur n'est pas très utile non plus, en fait, je trouve encore moins d'informations lorsque je recherche sur cette erreur que lorsque je recherche sur l'erreur précédente. Donc, je ne suis pas sûr que ce soit un pas dans la bonne direction. Quoi de mieux d'être rentré du serveur? Un statut 500 (Erreur interne du serveur) ou un statut 403 (Interdit)? De plus, si après avoir appliqué cette "solution", je change l'annotation en @PermitAll, la création d'un nouvel utilisateur fonctionne exactement comme avant, si bien que la situation n'a pas vraiment empiré.Cependant, je peux trouver le code source de RoleBasedSecurityFilter , qui indique qu'il renvoie la variable ForbiddenException. Cela montre qu'une certaine méthode isUserInRole doit renvoyer true, mais cela n'est pas le cas dans mon application. Je ne peux pas le faire retourner vrai. Cela me fait me demander, Est-il possible de désactiver RoleBasedSecurityFilter.Java de RESTEasy? .

J'ai également trouvé la question SO suivante: @RolesAllowed ne peut pas être résolu avec Jersey , auquel Abhijit Sarkar a répondu, et il fait référence à un article IBM . Peut-être que la solution à mon problème réside là-dedans, mais je ne l’ai pas encore trouvée .. Quoi qu’il en soit, il est suggéré d’ajouter un bloc security-role à mon fichier web.xml ou d’ajouter Une annotation @DeclareRoles dans mon fichier UserResource.Java devrait résoudre le problème, mais l'avertissement HTTP 403 Forbidden subsiste après cette opération. C'est très frustrant.

Mon bloc security-role (dans web.xml) se présente comme suit:.

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

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

login-config (avec FORM authentication ) à mon fichier web.xml. Modification de ma page HTML de connexion pour correspondre à le format requis . J'ai suivi une partie de l'étape de cet article sur la migration d'une application Java EE de GlassFish vers WildFly , mais je pense que j'ai quand même commis une erreur car je parviens toujours à la page d'erreur de connexion lorsque j'essaie de me connecter avec des informations d'identification valides. .

Voir ici l'élément security-domain que j'ai ajouté à ma configuration 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>

J'aimerais beaucoup savoir comment implémenter la sécurité basée sur les rôles pour mon application Web. Par conséquent, j'accepte également d'autres approches de la sécurité basée sur les rôles, tant que cela fonctionne. Les suggestions sont les bienvenues.

J'ai aussi placé ma question sur developer.jboss.org , mais je n'ai pas encore reçu de réponse.

J'ai fourni une solution de contournement à mon problème comme réponse à cette question, mais ce n'est pas une solution réelle (comme expliqué dans cette réponse). Je suis toujours intéressé à faire cela de la bonne façon.

I provided one workaround solution to my problem as an answer to this question, but it is not a real solution (as explained in that answer). I am still interested in doing this the right way.

15
PJvG

Je viens d'avoir le même problème. 

C'est l'annotation @Stateless. Les marques de votre classe en tant que EJB et le conteneur tente d'appliquer la sécurité EJB.

J'ai découvert cela en écrivant des filtres et mon propre SecurityContext, seulement pour constater que ma SecurityContext n'a jamais été référencée. 

La suppression de @Stateless a entraîné l'appel de getUserPrincipal() à la SecurityContext.

8
tptptp

Sur la base de l'erreur "403", il me semble qu'il y a un problème avec votre requête de rôle. Peut-être que votre module de connexion n'attribue pas le rôle "admin" à votre utilisateur. Une solution consiste à mettre en œuvre un mécanisme d’authentification personnalisé http://undertow.io/undertow-docs/undertow-docs-1.3.0/#authentication-mechanisms (exemple: https: // github. com/dstraub/spnego-wildfly ), et modifiez-le de manière à ce que vous puissiez vérifier les rôles que votre module de connexion attribue à votre utilisateur. L'implémentation d'un mécanisme d'authentification personnalisé va vous prendre un certain temps, mais cela vous aide à mieux comprendre le fonctionnement de la sécurité dans wildfly.

Une autre chose que je devais faire pour que mon annotation Roles fonctionne consiste à modifier le fichier standalone.xml et à définir votre domaine de sécurité comme domaine par défaut.

De plus, l'ajout de ces lignes est un pas dans la bonne direction, pour moi. Sans ces lignes, les annotations @RolesAllowed ne fonctionnent pas pour moi.

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

De plus, je vous conseillerais de mettre en œuvre la sécurité en utilisant seulement le fichier web.xml, et seulement après cela, essayez d’ajouter @RolesAllowed. 

4
Ievgen

J'ai trouvé une solution à mon problème. Cependant, ce n'est pas autant une solution au problème qu'il s'agit d'une workaround, car elle n'utilise pas l'annotation @RolesAllowed.

Étant donné que je ne pouvais pas comprendre comment définir exactement les descripteurs de déploiement et la configuration du serveur, j'ai pensé que le problème serait résolu beaucoup plus facilement si je n'utilisais tout simplement pas l'annotation @RolesAllowed.

Même si d'autres personnes pourraient vraiment souhaiter utiliser l'élément login-config dans leur fichier web.xml et ne pas utiliser d'autre moyen d'authentification, cette approche n'utilise pas cet élément, mais utilise plutôt l'authentification via RESTful Web Services (ce qui signifie que rien ne doit changer dans les descripteurs de déploiement ou la configuration du serveur).

J'ai créé un nouveau (Enterprise Enterprise Bean (EJB) Java) appelé SecurityFilter qui vérifie si un utilisateur dispose des rôles requis pour certaines fonctionnalités. Il est implémenté comme suit:

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

La méthode isUserAllowed est appelée dans la méthode create de UserResource.Java. L'ancienne implémentation de cette méthode create peut être vue dans la question ci-dessus. La nouvelle implémentation est la suivante:

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

Comme vous pouvez le constater, une instruction if-else remplace l'annotation @RolesAllowed dans cette approche et mon filtre de sécurité est implémenté légèrement différemment.

De plus, cette approche utilise HttpHeaders pour obtenir les en-têtes de requête (dans lesquels l'ID utilisateur et le jeton sont stockés). La réponse acceptée sur la question SO " comment recevoir l'en-tête" Accepter "dans le serveur de service Web REST " m'a aidé à trouver comment obtenir les en-têtes de requête .

De plus, cette approche fonctionne sans rien changer dans mes pages Web à base de Backbone.js _ et Bootstrap (c'est-à-dire mes fichiers HTML et JavaScript).

1
PJvG

J'ai vu votre message sur ma réponse ici . Je ne connais pas très bien la sécurité propriétaire de JBoss et je ne recommande pas non plus de l'inclure dans le code, mais je suppose que ce n'est pas mon problème. De votre code, je ne vois pas security-role ou @DeclareRoles présent; Il est clairement indiqué dans ma réponse que vous avez besoin de l'un ou l'autre pour que la sécurité basée sur les annotations fonctionne. Avez-vous exclu cela par souci de brièveté ou l'avez-vous manqué? Si c'est le cas, ajoutez @DeclareRoles à la classe UserResource et voyez si cela vous aide.

0
Abhijit Sarkar