【问题标题】:Glassfish, EJB3, SOAP web service and basic authenticationGlassfish、EJB3、SOAP Web 服务和基本身份验证
【发布时间】:2010-10-10 02:05:41
【问题描述】:

我正在设置一个带有单个 EJB3 的 glassfish 服务器作为 POC 的模拟后端。在我添加一些基本身份验证之前,一切都运行良好。只需计划文本用户名和密码,这项工作没有什么复杂的。我在 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 元素的值应该是什么的东西。所以我不知道我是否做对了。

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 是的,我也遇到过。起初,我在 glassfish 的文件领域中有一个名为“user”的组,在 EJB 中还有一个名为“user”的角色。然后我尝试添加一个安全角色映射并将 glasshfish 组更改为“客户”,根据您的示例将“用户”映射到“客户”。它不起作用。每次我重新加载包含 ejb 的 ear 文件时,我都会看到来自 Glassfish 的消息说“没有映射到角色“用户”的主体。我怀疑这是问题的核心。
    • 我还看到一条关于两个 ejb(虽然我只有一个)被映射为同名的消息。如果我注释掉 @Stateless 注释,消息就会消失。但是,所有身份验证也被关闭。所以我似乎需要那个注释。
    【解决方案2】:

    我认为您当前没有为基本身份验证创建适当的 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. 使用目录提供对 WSDL 的本地访问。有目录 jax-ws 发行版中的示例。
    3. 配置 web.xml 以允许未经身份验证的 GET 请求

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

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

    另见

    【讨论】:

    • 我使用的是 SoapUI,它生成的是 xml。
    • @Derek 这会有所帮助吗:thewonggei.wordpress.com/2010/08/05/…
    • Okies,在 xml 中发现了一些错误,因为我手动输入了安全部分。我已经在上面的代码中修复了这些,并在 SoapUI 中重新测试。 Soap 消息是正确的,这是 ws-security 标头的正确布局。我以前曾将它们用于基本安全性和许多 SoapUI 测试。通常我将用户添加到 SoapUI 项目并在 SoapUI 身份验证设置中的 Soap 请求中设置它。 SoapUI 然后使用嵌入的 ws-security 元素生成此消息。
    • @Derek 我的意思是,您的问题中没有任何内容可以得出以下结论:基本身份验证的 HTTP 标头 已正确定义(ws-security 标头与问题无关) ,因此我的回答:)
    • 好吧。您的回答让我感到困惑,因为我没有使用 http 标头来验证肥皂请求。如上所述,始终在 SOAP 标头中使用 ws-security 元素。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 2013-12-01
    • 1970-01-01
    相关资源
    最近更新 更多