Glassfish,EJB3,SOAP Web服务和基本身份验证

时间:2010-10-10 02:05:42

标签: web-services authentication soap glassfish ejb-3.0

我正在设置一个带有单个EJB3的glassfish服务器作为POC的模拟后端。在我添加一些基本身份验证之前,一切正常。只需计划文本用户ID和密码,这项工作没什么复杂的。我在EJB中添加了以下注释:

@WebService(name = "Banking", serviceName = "Banking", targetNamespace = BANKING_NAMESPACE)
@DeclareRoles("user")
@Stateless
public class Banking {
    ...

    @RolesAllowed("user")
    @SOAPBinding(parameterStyle = ParameterStyle.BARE)
    @WebMethod(action = BANKING_NAMESPACE + "/logon", operationName = "logon")
    @WebResult(targetNamespace = XmlStrings.BANKING_MODEL_NAMESPACE)
    public LogonResponse logon(@WebParam(targetNamespace = XmlStrings.BANKING_MODEL_NAMESPACE) Logon request) throws WebServiceException {
     ...
    }
}

根据我读过的EJB3规范,这对于执行SOAP Web服务非常常见。

但是当我发送这个xml时:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mod="http://www.dhcbank.com/banking/model">
    <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <wsse:UsernameToken wsu:Id="UsernameToken-79" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <wsse:Username>fred</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">fred</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <mod:logon/>
    </soapenv:Body>
</soapenv:Envelope>

我将以下错误作为SOAP错误返回:

java.lang.Exception: Client not authorized for invocation of public com.dhcbank.www.banking.schema.LogonResponse com.dhcbank.www.banking.Banking.logon(com.dhcbank.www.banking.schema.Logon) throws javax.xml.ws.WebServiceException

在glassfish日志中:

[#|2010-10-10T12:49:27.497+1100|INFO|glassfish3.0.1|javax.enterprise.system.core.security|_ThreadID=41;_ThreadName=http-thread-pool-8080-(2);|JACC Policy Provider: Failed Permission Check, context(BankingEAR/Banking_war_internal)- permission((javax.security.jacc.EJBMethodPermission Banking logon,ServiceEndpoint,com.dhcbank.www.banking.schema.Logon))|#]

在glassfish管理界面中,我添加了一个名为fred的用户,其中包含一个fred密码,并将其分配给名为user的组。但那没用。

我做了一些阅读,建议我创建一个sun-ejb-jar.xml文件并将其添加到ear文件中。所以我用这个内容创建了它:

<sun-ejb-jar>
    <enterprise-beans>
        <ejb>
            <ejb-name>Banking</ejb-name>
            <webservice-endpoint>
                <port-component-name>Banking</port-component-name>
                    <login-config>
                        <auth-method>BASIC</auth-method>
                        <realm>file</realm>
                </login-config>
            </webservice-endpoint>               
        </ejb>
    </enterprise-beans>
</sun-ejb-jar>

这就像我所知道的那样,正确。但是我找不到任何告诉我port-component-name元素的值应该是什么的东西。所以我不知道我是否做得对。

安全性似乎仍然没有起作用,我无法弄清楚原因。有没有人有这方面的经验,可以指出我做错了什么或没做过什么?

2 个答案:

答案 0 :(得分:2)

我假设您声明的角色“user”与文件领域中的角色名称相同?如果不在描述符中提供此映射:

<sun-ejb-jar>
   <security-role-mapping>
     <role-name>user</role-name>
     <group-name>filerealm-group-name</group-name>
   </security-role-mapping>
   ...

答案 1 :(得分:1)

我认为您目前没有为基本身份验证创建适当的HTTP标头。我不确定如何创建SOAP请求,但如果您使用的是JAX-WS客户端,则JAX-WS FAQ会记录以下内容:

  

Q. How do I do basic authentication in JAX-WS?

     

您可以执行以下操作:

HelloService service = new HelloService();
Hello proxy = (service.getHelloPort());
((BindingProvider)proxy).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userfoo");
((BindingProvider)proxy).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "passbar");
     

USERNAME_PROPERTY,PASSWORD_PROPERTY   主要用于服务   要求。我想当你实例化的时候   服务,它获取WSDL和   服务器返回401.你可以试试   以下任何一种解决方案。

     
      
  1. 在客户端应用程序中使用java.net.Authenticator类。
  2.   
  3. 使用目录提供对WSDL的本地访问。有一个目录   样本在jax-ws发行版中。
  4.   
  5. 配置web.xml以允许无需身份验证的GET请求
  6.   

除非我错了,否则如果web服务需要在SOAP标头中进行身份验证,则usernametoken将适合,根据您的描述,情况并非如此。

换句话说,对我来说,您目前没有发送BASIC身份验证的凭据。

另见