2012-01-31 15 views
6

¿Es posible utilizar la anotación @RolesAllowed en un servicio web JAX-WS y, en caso afirmativo, cómo?JAX-WS webservice y @rolesAllowed

Tengo un servicio web en glassfish 3.1.1 usando Basic Authentication pero las restricciones expresadas usando @RolesAllowed se ignoran. La información debe estar disponible papel, como puedo acceder a él de esta manera:

@Resource 
WebServiceContext wsContext; 

if (wsContext.isUserInRole("READ")) 
log.info("Role: READ"); 

recibo el papel que se espera, pero todavía todos los métodos son accesibles, incluso si @RolesAllowed se establece en función diferente. @DenyAll no está funcionando tan bien.

Si estas anotaciones no son compatibles, ¿es posible usar descriptores de implementación para administrar el acceso a los métodos del servicio web en función de las funciones de los usuarios?

Editar: This parte de la 6 tutorial JAVA EE describe el uso de @RolesAllowed anotación. Se lee

Para los componentes de Java EE, usted define los roles de seguridad utilizando las anotaciones de metadatos @DeclareRoles y @RolesAllowed.

servicios Web no aparecen como componentes de Java EE en la primera parte del tutorial, lo que parece que las anotaciones de seguridad no son compatibles.

Edit2 Después de la publicación de Izan, le di otra oportunidad. Esto es lo que hice:

@Webservice 
@DeclareRoles(value = {"READ", "UPDATE", "DELETE"}) 
public class ServiceImpl implements Service { 
    @Override 
    @WebMethod(operationName = "helloWorld") 
    @RolesAllowed({"NONE"}) 
    public String helloWorld() throws Exception { 
    return "Hello World!"; 
    } 
} 

Usando este tipo de configuración, todos pueden acceder al método, sin importar los roles que se establezcan. Los usuarios se autentican (pueden ver eso en audit.log) pero no se realiza ninguna autorización. Como se indicó anteriormente, puedo acceder a la función desde WebServiceContext (en realidad hago la autorización manual usando esta información).

Añadiendo la anotación @Stateless, vamos a usar las anotaciones de seguridad. Entonces @permitAll funciona como se esperaba. Pero el uso de roles aún no funciona, ya que el usuario no se autentica ahora. Aparecen como ANONYMOUS en el registro de auditoría y se les niega el acceso.

Mi web.xml se parece a esto:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> 
<display-name>OneMore</display-name> 

<security-constraint> 
    <display-name>WebServiceSecurity</display-name> 

    <web-resource-collection> 
     <web-resource-name>Authorized users only</web-resource-name> 
     <url-pattern>/service</url-pattern> 
     <http-method>POST</http-method> 
    </web-resource-collection> 

    <auth-constraint>  
     <role-name>READ</role-name> 
     <role-name>UPDATE</role-name> 
     <role-name>DELETE</role-name> 
    </auth-constraint> 

</security-constraint> 

<login-config> 
    <auth-method>BASIC</auth-method> 
</login-config> 

<security-role> 
    <role-name>READ</role-name> 
</security-role> 

<security-role> 
    <role-name>UPDATE</role-name> 
</security-role> 

<security-role> 
    <role-name>DELETE</role-name> 
</security-role> 
</web-app> 

Glassfish-web.xml acaba de mapas de nombres de roles a los nombres de grupos, así:

<security-role-mapping> 
    <role-name>READ</role-name> 
    <group-name>READ</group-name> 
</security-role-mapping> 

Editar 3 Gracias a Izan e innumerables intentos más tarde por fin lo tengo trabajando.

Como dije antes, el punto principal fue cambiar de un servicio web simple a un servicio web EJB al agregar la anotación @Stateless. Esto permite usar las anotaciones de seguridad.

Este cambio también es necesario para cambiar los descriptores de despliegue. Mientras que el servicio web original requirió un glassfish-web.xml para configurar los roles, se requiere un glassfish-ejb-jar.xml posteriormente.

Respuesta

6

Tal vez esta es una pregunta bastante tonta, pero ¿son sus EJB de servicios web? Como se señaló en Security Annotations and Authorization in GlassFish and the Java EE 5 SDK

Las anotaciones @PermitAll, @DenyAll y @RolesAllowed se definen para la especificación de permisos del método de negocio EJB

uso esas anotaciones con WS de abajo hacia arriba de sin estado EJBs y trabajan como un encanto en JBoss.


EDIT 1 @TPete voy a añadir algo de código para mostrar más o menos lo que estoy haciendo.

@Stateless 
@WebService() 
@WebContext(contextRoot = WSContextRoot.CTX_ROOT, 
    authMethod = "BASIC") 
@EndpointConfig(configName = "Standard WSSecurity Endpoint") 
@SecurityDomain(value = "myDeclaredDomain") 
@RolesAllowed({ "AUTHORISED" }) 
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT) 
public class MyWS implements MyInterface { 
    @Override 
    public void doSomething(){ 
     //impl 
    } 
} 

Y en cuanto a la interfaz

@Remote 
@WebService 
public interface MyInterface { 

    @WebMethod(operationName="doSomething") 
    public void doSomething(); 
} 

WebContext, EndpointConfig y SecurityDomain son JBoss anotación, pero supongo que hay algo similar para GlassFish, o de forma equivalente de hacerlo. El dominio de seguridad se incluye en un descriptor de implementación para jboss, y se define en el archivo login-config.xml a partir de los archivos de configuración de JBoss.


EDIT 2 @TPete

supongo que es necesario agregar algunos descriptores de despliegue EJB de Glassfish, un sol-ejb-jar.xml paquete archivo dentro de su oído. Una vez más, desde el mismo artículo que ha escrito en la respuesta, hay una El uso de los descriptores de implementación capítulo que establece

Para extremos de servicio EJB web con @RolesAllowed, es necesario especificar el tipo de autenticación que se utilizará especificando el y elementos en sun-ejb-jar.xml. Para la autenticación de nombre de usuario y contraseña, establezca el elemento en BASIC, como se muestra en el siguiente ejemplo. Este paso solo es necesario para los puntos finales del servicio web EJB, y no es obligatorio para los EJB.

Dado que está definiendo un punto final del servicio web EJB, creo que debe poner este descriptor en su EAR. Eche un vistazo rápido a ese artículo, describe bastante bien el proceso que está siguiendo :-)

+0

Lo sentimos, tal vez podría haber publicado esto como una edición en lugar de una respuesta. – igracia

+0

Creo que publicarlo como un comentario sería lo más apropiado, aunque hasta que tengas 50 representantes no es posible – Flexo

+0

@Izan Supongo que no, aunque este es mi primer proyecto Java EE y no estoy tan familiarizado con la terminología. Tal vez publicar un ejemplo podría aclarar el problema. Solo uso la anotación '@ Webservice' en este momento. Intenté combinarlo con '@ Stateless', pero luego no pude acceder al servicio web utilizando Https. – TPete

0

La pregunta original es vieja, pero aún estoy dejando un comentario en caso de que alguien como yo tropiece con ella. Comenzando con EJB 3.1, los EJB pueden estar empaquetados en un módulo WAR, pero cuando se trata de protegerlos, se deben usar los descriptores de despliegue EJB. Lo que no está claro en la especificación es que los EJB pueden no declararse como servlets en web.xml o de lo contrario la aplicación no podrá iniciarse.

He aquí un excelente artículo sobre el envasado de los EJB en los módulos de la guerra y las diferencias con el empaquetado de módulos JAR EJB: http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.multiplatform.doc%2Finfo%2Fae%2Fae%2Fcejb_ejbinwar.html