Securing Web Service - Basic Authentication

I'm trying to secure a web service using basic authentication. I'm using Sun Java System Application Server Platform Edition 9.0_01 (build b14).

Here's the basics of the web service:

@Stateless

@WebService

public class EnityCrudWS {

@EJB private EntityCrudLocal<Vendor> vendorBean;

@WebMethod

@WebResult(name="Vendor")

@RolesAllowed("users")

public Collection<Vendor> getAllVendors() {

return vendorBean.getAll(Vendor.class);

}

}

I've edited the sun-ejb-jar.xml file to enable basic authentication on this web service and do the security role to security group mappings:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">

<sun-ejb-jar>

<security-role-mapping>

<role-name>users</role-name>

<group-name>users</group-name>

</security-role-mapping>

<enterprise-beans>

<ejb>

<ejb-name>EntityCrudWS</ejb-name>

<webservice-endpoint>

<port-component-name>EntityCrudWS</port-component-name>

<login-config>

<auth-method>BASIC</auth-method>

<realm>file</realm>

</login-config>

</webservice-endpoint>

</ejb>

</enterprise-beans>

</sun-ejb-jar>

I've added a user, s148222, to the 'file' realm who's group list is 'users'. I thought that's all I would need to do - but it's not working. Here's the exceptions from the server's log:

DPL5306:EJB Web Service Endpoint [EntityCrudWS] listening at address [http://p3031727.aepsc.com:8080/EntityCrudWSService/EntityCrudWS]

Logging in user [s148222] into realm: file using JAAS module: fileRealm

Login module initialized: class com.sun.enterprise.security.auth.login.FileLoginModule

File login succeeded for: s148222

JAAS login complete.

JAAS authentication committed.

Password login succeeded for : s148222

Set security context as user: s148222

JACC: permission initialized in InvocationInfo: EJBMethodPermission (Name) = EntityCrudWS (Action) = getAllVendors,ServiceEndpoint,

JACC: new ProtectionDomain added to cache

JACC: returning cached ProtectionDomain - CodeSource: ((file:/CSPSPrototypeGenerics/CSPSPrototypeGenerics-ejb_jar <no signer certificates>)) PrincipalSet: s148222 users

JACC Policy Provider: PolicyWrapper.implies, context(CSPSPrototypeGenerics/CSPSPrototypeGenerics-ejb_jar)- permission((javax.security.jacc.EJBMethodPermission EntityCrudWS getAllVendors,ServiceEndpoint,)) domain that failed(ProtectionDomain (file:/CSPSPrototypeGenerics/CSPSPrototypeGenerics-ejb_jar <no signer certificates>)

null

(principals com.sun.enterprise.deployment.PrincipalImpl "s148222",

com.sun.enterprise.deployment.Group "users")

java.security.Permissions@1e53662 (

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS wait,ServiceEndpoint,long)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS equals,ServiceEndpoint,java.lang.Object)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS wait,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS notify,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS getClass,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS hashCode,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudBean getAll,Local,java.lang.Class)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS toString,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS wait,ServiceEndpoint,long,int)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudWS notifyAll,ServiceEndpoint,)

(unresolved javax.security.jacc.EJBMethodPermission EntityCrudBean ,Local)

(unresolved com.sun.enterprise.security.CORBAObjectPermission * *)

(java.util.PropertyPermission line.separator read)

(java.util.PropertyPermission java.vm.version read)

(java.util.PropertyPermission java.vm.specification.version read)

(java.util.PropertyPermission java.vm.specification.vendor read)

(java.util.PropertyPermission java.vendor.url read)

(java.util.PropertyPermission java.vm.name read)

(java.util.PropertyPermission * read)

(java.util.PropertyPermission os.name read)

(java.util.PropertyPermission java.vm.vendor read)

(java.util.PropertyPermission path.separator read)

(java.util.PropertyPermission java.specification.name read)

(java.util.PropertyPermission os.version read)

(java.util.PropertyPermission os.arch read)

(java.util.PropertyPermission java.class.version read)

(java.util.PropertyPermission java.version read)

(java.util.PropertyPermission file.separator read)

(java.util.PropertyPermission java.vendor read)

(java.util.PropertyPermission java.vm.specification.name read)

(java.util.PropertyPermission java.specification.version read)

(java.util.PropertyPermission java.specification.vendor read)

(java.io.FilePermission C:\Temp\\- delete)

(java.io.FilePermission E:/Program Files/Sun/GlassFish/domains/domain1\lib\databases\- delete)

(java.io.FilePermission <<ALL FILES>> read,write)

(javax.security.auth.PrivateCredentialPermission javax.resource.spi.security.PasswordCredential * "*" read)

(java.net.SocketPermission localhost:1024- listen,resolve)

(java.net.SocketPermission * connect,resolve)

(javax.management.MBeanPermission [com.sun.messaging.jms.*:*] *)

(java.lang.RuntimePermission loadLibrary.*)

(java.lang.RuntimePermission accessDeclaredMembers)

(java.lang.RuntimePermission modifyThreadGroup)

(java.lang.RuntimePermission stopThread)

(java.lang.RuntimePermission queuePrintJob)

(javax.management.MBeanTrustPermission register)

)

)

JACC: Access Control Decision Result: false EJBMethodPermission (Name) = EntityCrudWS (Action) = getAllVendors,ServiceEndpoint, (Caller) = null

Client not authorized to access public java.util.Collection com.aep.csps.si.ws.EntityCrudWS.getAllVendors()

javax.ejb.AccessLocalException: Client not authorized to access public java.util.Collection com.aep.csps.si.ws.EntityCrudWS.getAllVendors()

at com.sun.ejb.containers.WebServiceInvocationHandler.invoke(WebServiceInvocationH andler.java:128)

at $Proxy115.getAllVendors(Unknown Source)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.ja va:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at com.sun.xml.ws.server.PeptTie._invoke(PeptTie.java:61)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.invokeEndpoint(SOAPMe ssageDispatcher.java:280)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher$SoapInvoker.invoke(SO APMessageDispatcher.java:588)

at com.sun.xml.ws.protocol.soap.server.SOAPMessageDispatcher.receive(SOAPMessageDi spatcher.java:147)

at com.sun.xml.ws.server.Tie.handle(Tie.java:90)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.handlePost(Ejb3MessageDispa tcher.java:160)

at com.sun.enterprise.webservice.Ejb3MessageDispatcher.invoke(Ejb3MessageDispatche r.java:89)

at com.sun.enterprise.webservice.EjbWebServiceServlet.dispatchToEjbEndpoint(EjbWeb ServiceServlet.java:186)

at com.sun.enterprise.webservice.EjbWebServiceServlet.service(EjbWebServiceServlet .java:117)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

at com.sun.enterprise.web.AdHocContextValve.invoke(AdHocContextValve.java:101)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:71)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java: 120)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:13 7)

at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)

at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)

at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)

at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:239)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorT ask.java:667)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked(Proces sorTask.java:574)

at com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.ja va:844)

at com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask .java:287)

at com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)

at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)

at com.sun.enterprise.web.connector.grizzly.WorkerThread.run(WorkerThread.java:75)

What I find interesting is at the JACC Access Control Decision Result it appears as though the caller is null. I've been thinking this must be the problem but I don't understand what it's null when clearly the JAAS module successfully logged-in s148222.

Can anyone see what I'm doing wrong?

[10281 byte] By [taylodla] at [2007-11-26 20:56:19]
# 1

More information. I added the following to the EntityCrudWS class:

@Resource private SessionContext sc;

@WebMethod

@WebResult(name="Principal")

public String getCallingPrincipal() {

return sc.getCallerPrincipal().getName() + "-" + sc.isCallerInRole("users");

}

It's returning "s148222-false". Now I need to figure out why it isn't seeing that the principal is in the role, but at least I know the client is successfully providing the basic auth credentials and that the principal is being correctly established.

taylodla at 2007-7-10 2:24:36 > top of Java-index,Application & Integration Servers,Application Servers...
# 2

I've tracked it down to being a role mapping issue. If I make the role name and the principal's group name the same and enable the Default Principal To Role Mapping: from the security console then I can get everything to work.

What I can't seem to do is map a security role to a group, even though I have the following in my sun-ejb-jar file:

<security-role-mapping>

<role-name>users</role-name>

<group-name>csps-users</group-name>

</security-role-mapping>

Does anyone know how to do the mapping?

taylodla at 2007-7-10 2:24:37 > top of Java-index,Application & Integration Servers,Application Servers...
# 3

> I've tracked it down to being a role mapping issue.

> If I make the role name and the principal's group

> name the same and enable the Default

> Principal To Role Mapping: from the security

> console then I can get everything to work.

Yep, that's the way to go when you don't want to use a group to role mapping -- just make them the same and use the Default Principal to Role Mapping.

For your case, are you sure that you turned off default mapping before deploying? The mapping takes place at deployment time, so you can't deploy and then make that change. One thing to note: there was a bug that default mapping couldn't be turned off unless you restarted the server, but that has been fixed: https://glassfish.dev.java.net/issues/show_bug.cgi?id=2387

><security-role-mapping>

><role-name>users</role-name>

><group-name>csps-users</group-name>

> </security-role-mapping>

Are you sure that the "csps-users" group exists and that the user you are using is in that group? There are some security devtests that you may be able to look at to see what's going on:

https://glassfish.dev.java.net/source/browse/glassfish/appserv-tests/devtests/s ecurity/wss/roles2/

The tests use a lot of infrastructure to add users, create and deploy apps, etc., but there are examples of the descriptor files that might show you what's going on. If not, I can try an example for you (but not until tomorrow probably).

Cheers,

Bobby

sunbobbya at 2007-7-10 2:24:37 > top of Java-index,Application & Integration Servers,Application Servers...
# 4

Thanks for the help. I've turned off default role mapping, undeployed the application, restarted the server and then redeployed the application. Same result.

I'm pretty sure the 'csps-users' group exists. When I go to manage the users of the group in the realm, and I edit the user I'm using, 'csps-users' is the value in the group list. Is that sufficient?

taylodla at 2007-7-10 2:24:37 > top of Java-index,Application & Integration Servers,Application Servers...