Hi,
You may also want to check "Metro" documentation for advanced security, but a quite compatible solution for Glassfish v1 & v2 to restrict access to webservice methods with username + password is using the "sun-ejb-jar.xml" deployment descriptor to define "webservice-endpoint" authentication type/realm, and security role mappings. When it is required SSL, you only have to change "transport-guarantee" tag value to "CONFIDENTIAL" (and it is also useful to change WSDL published location in "webservice-description" to an "https" URL address).
On the implementation code side, you should also define all the roles with the "javax.annotation.security.DeclareRoles" annotation.
For example, if we had implemented the webservice with this EJB:
[code]
package ws;
import javax.annotation.Resource;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.RolesAllowed;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService()
@Stateless()
@DeclareRoles({"UserRole"})
public class WsEJB
{
@Resource
private SessionContext sessionContext;
@WebMethod(operationName = "getPrincipalName")
@RolesAllowed({"UserRole"})
public String getPrincipalName() {
return sessionContext.getCallerPrincipal().getName();
}
}
[code]
Then, you can use the following "sun-ejb-jar.xml" to enable basic username+password authentication on "file" realm (without SSL):
[code]
<?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>UserRole</role-name>
<group-name>users</group-name>
</security-role-mapping>
<enterprise-beans>
<ejb>
<ejb-name>WsEJB</ejb-name>
<jndi-name>ws.WsEJB</jndi-name>
<ior-security-config>
<transport-config>
<integrity>NONE</integrity>
<confidentiality>NONE</confidentiality>
<establish-trust-in-target>NONE</establish-trust-in-target>
<establish-trust-in-client>NONE</establish-trust-in-client>
</transport-config>
<as-context>
<auth-method>username_password</auth-method>
<realm>file</realm>
<required>true</required>
</as-context>
<sas-context>
<caller-propagation>NONE</caller-propagation>
</sas-context>
</ior-security-config>
<webservice-endpoint>
<port-component-name>WsEJB</port-component-name>
<login-config>
<auth-method>BASIC</auth-method>
<realm>file</realm>
</login-config>
<transport-guarantee>NONE</transport-guarantee>
</webservice-endpoint>
</ejb>
<webservice-description>
<webservice-description-name>WsEJBService</webservice-description-name>
<wsdl-publish-location>
http://localhost:8080/WsEJBService/WsEJB?WSDL</wsdl-publish-location>
</webservice-description>
</enterprise-beans>
</sun-ejb-jar>
[code]
Note the "UserRole" mapping to a suposed "users" group in "file" realm.
Finally, to test the previous webservice, you can use the following code:
[code]
package wstest;
import java.util.Map;
import javax.xml.ws.BindingProvider;
// jax-ws stubs:
import ws.WsEJB;
import ws.WsEJBService;
public class Main
{
public static void main(String[] args)
{
WsEJBService service = new WsEJBService();
WsEJB port = service.getWsEJBPort();
Map<String,Object> context = ((BindingProvider)port).getRequestContext();
context.put(BindingProvider.USERNAME_PROPERTY, "username");
context.put(BindingProvider.PASSWORD_PROPERTY, "secretpassword");
context.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "
http://localhost:8080/WsEJBService/WsEJB");
System.out.println("Hello " + port.getPrincipalName());
}
}
[code]
I hope it works for your webservice.
[Message sent by forum member 'jmarine' (jmarine)]
http://forums.java.net/jive/thread.jspa?messageID=284827