2013年6月8日星期六

JDev_040:使用JDeveloper开发WebService之七:增加安全策略

开发运行环境:JDeveloper 11.1.2.4

本文介绍如何为Web Service添加OWSM安全策略,并调用它。

步骤说明:

1. 开发Web Service:Project1
具体步骤请参考《使用JDeveloper开发WebService之一:元注释驱动POJO(1)》。

2. 生成Web Service Proxy调用Web Service: Project2
具体步骤请参考《使用JDeveloper开发WebService之四:创建Web Service Proxy》。

3. 测试,确保增加安全策略前,可以正确调用Web Servcie。

4. 为Web Service增加OWSM安全策略:oracle/wss_username_token_service_policy
(1)右键Web Service,选择Web Service Properties,选择Configure Policies,勾上“oracle/wss_username_token_service_policy”
 (2)运行,并测试,这时调用会抛出如下异常,这是因为调用方没有增加安全策略:
<WsmMessageLogger> <logSevere> 安全标头缺失。请确保存客户端上附加了有效的安全策略, 并且策略已启用。
<WsmMessageLogger> <logSevere> 接收请求时出错: oracle.wsm.security.SecurityException: WSM-00069 : The security header is missing. Ensure that there is a valid security policy attached at the client side, and the policy is enabled.。
<WsmMessageLogger> <logSevere> 未能执行断言 {http://schemas.oracle.com/ws/2006/01/securitypolicy}wss-username-token 执行程序类 oracle.wsm.security.policy.scenario.executor.WssUsernameTokenScenarioExecutor。
<WsmMessageLogger> <logSevere> 由于异常错误, 未能执行 WS-Policy。
<WsmMessageLogger> <logSevere> Oracle WSM 代理 processRequest 失败, 类别=security, 函数=agent.function.service, 应用程序=SampleWS, 组合=null, modelObj=Service, 策略=oracle/wss_username_token_service_policy, policyVersion=null, assertionName={http://schemas.oracle.com/ws/2006/01/securitypolicy}wss-username-token。
<WSMAgentHook> <handleException> WSMAgentHook: An Exception is thrown:
oracle.wsm.common.sdk.WSMException: InvalidSecurity : 处理 WS-Security 安全标头时出错
at oracle.wsm.security.policy.scenario.executor.WssUsernameTokenScenarioExecutor.receiveRequest(WssUsernameTokenScenarioExecutor.java:197)
at oracle.wsm.security.policy.scenario.executor.SecurityScenarioExecutor.execute(SecurityScenarioExecutor.java:562)
at oracle.wsm.policyengine.impl.runtime.AssertionExecutor.execute(AssertionExecutor.java:41)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeSimpleAssertion(WSPolicyRuntimeExecutor.java:669)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeAndAssertion(WSPolicyRuntimeExecutor.java:346)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.execute(WSPolicyRuntimeExecutor.java:294)
at oracle.wsm.policyengine.impl.PolicyExecutionEngine.execute(PolicyExecutionEngine.java:102)
at oracle.wsm.agent.WSMAgent.processCommon(WSMAgent.java:1001)
at oracle.wsm.agent.WSMAgent.processRequest(WSMAgent.java:470)
at oracle.wsm.agent.handler.WSMEngineInvoker.handleRequest(WSMEngineInvoker.java:373)
at oracle.wsm.agent.handler.wls.WSMAgentHook.handleRequest(WSMAgentHook.java:305)
at weblogic.wsee.jaxws.framework.jaxrpc.TubeFactory$JAXRPCTube.processRequest(TubeFactory.java:222)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:866)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:815)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:778)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:680)
at com.sun.xml.ws.server.WSEndpointImpl$2.process(WSEndpointImpl.java:403)
at com.sun.xml.ws.transport.http.HttpAdapter$HttpToolkit.handle(HttpAdapter.java:532)
at com.sun.xml.ws.transport.http.HttpAdapter.handle(HttpAdapter.java:253)
at com.sun.xml.ws.transport.http.servlet.ServletAdapter.handle(ServletAdapter.java:140)
at weblogic.wsee.jaxws.WLSServletAdapter.handle(WLSServletAdapter.java:171)
at weblogic.wsee.jaxws.HttpServletAdapter$AuthorizedInvoke.run(HttpServletAdapter.java:708)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:146)
at weblogic.wsee.util.ServerSecurityHelper.authenticatedInvoke(ServerSecurityHelper.java:103)
at weblogic.wsee.jaxws.HttpServletAdapter$3.run(HttpServletAdapter.java:311)
at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:336)
at weblogic.wsee.jaxws.JAXWSServlet.doRequest(JAXWSServlet.java:95)
at weblogic.servlet.http.AbstractAsyncServlet.service(AbstractAsyncServlet.java:99)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:119)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:442)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:103)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:171)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:139)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

5. 调用增加了安全策略的Web Service: Project3
生成Proxy时,选择勾上“oracle/wss_username_token_client_policy”。

增加客户端安全策略之后,还要设置用户名/口令,否则直接调用会报出如下异常:
严重: WSM-00016 用户名/口令身份证明或证书null缺失。
严重: WSM-00005 发送请求时出错。
严重: WSM-07607 未能执行断言 {http://schemas.oracle.com/ws/2006/01/securitypolicy}wss-username-token 执行程序类 oracle.wsm.security.policy.scenario.executor.WssUsernameTokenScenarioExecutor。
严重: WSM-07602 由于异常错误, 未能执行 WS-Policy。
严重: WSM-07501 Oracle WSM 代理 processRequest 失败, 类别=security, 函数=agent.function.client, 应用程序=null, 组合=null, modelObj=Service, 策略=oracle/wss_username_token_client_policy, policyVersion=null, assertionName={http://schemas.oracle.com/ws/2006/01/securitypolicy}wss-username-token。
oracle.wsm.common.sdk.WSMException: WSM-00015 : 用户名缺失。
at oracle.wsm.security.policy.scenario.executor.WssUsernameTokenScenarioExecutor.sendRequest(WssUsernameTokenScenarioExecutor.java:228)
at oracle.wsm.security.policy.scenario.executor.SecurityScenarioExecutor.execute(SecurityScenarioExecutor.java:577)
at oracle.wsm.policyengine.impl.runtime.AssertionExecutor.execute(AssertionExecutor.java:41)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeSimpleAssertion(WSPolicyRuntimeExecutor.java:669)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.executeAndAssertion(WSPolicyRuntimeExecutor.java:346)
at oracle.wsm.policyengine.impl.runtime.WSPolicyRuntimeExecutor.execute(WSPolicyRuntimeExecutor.java:294)
at oracle.wsm.policyengine.impl.PolicyExecutionEngine.execute(PolicyExecutionEngine.java:102)
at oracle.wsm.agent.WSMAgent.processCommon(WSMAgent.java:1001)
at oracle.wsm.agent.WSMAgent.processRequest(WSMAgent.java:470)
at oracle.wsm.agent.handler.WSMEngineInvoker.handleRequest(WSMEngineInvoker.java:373)
at oracle.wsm.agent.handler.wls.WSMAgentHook.handleRequest(WSMAgentHook.java:305)
at weblogic.wsee.jaxws.framework.jaxrpc.TubeFactory$JAXRPCTube.processRequest(TubeFactory.java:222)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:866)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:815)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:778)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:680)
at com.sun.xml.ws.client.Stub.process(Stub.java:272)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:153)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:115)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:95)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:136)
at com.sun.proxy.$Proxy33.salaryUpgrade(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at weblogic.wsee.jaxws.spi.ClientInstanceInvocationHandler.invoke(ClientInstanceInvocationHandler.java:84)
at com.sun.proxy.$Proxy34.salaryUpgrade(Unknown Source)
at a.ServicePortClient.main(ServicePortClient.java:23)
Caused by: oracle.wsm.security.SecurityException: WSM-00015 : 用户名缺失。
at oracle.wsm.security.policy.scenario.processor.UsernameTokenProcessor.build(UsernameTokenProcessor.java:450)
at oracle.wsm.security.policy.scenario.executor.WssUsernameTokenScenarioExecutor.sendRequest(WssUsernameTokenScenarioExecutor.java:212)
... 28 more

完整的调用代码如下:
package a;

import java.util.Date;
import java.util.GregorianCalendar;

import java.util.Map;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import javax.xml.ws.BindingProvider;

import weblogic.wsee.jws.jaxws.owsm.SecurityPoliciesFeature;
// This source file is generated by Oracle tools.
// Contents may be subject to change.
// For reporting problems, use the following:
// Generated by Oracle JDeveloper 11g Release 2 11.1.2.4.0.6436

public class ServicePortClient {
    public static void main(String[] args) {
        Service_Service service_Service = new Service_Service();

        // Configure security feature
        SecurityPoliciesFeature securityFeatures =
            new SecurityPoliciesFeature(new String[] { "oracle/wss_username_token_client_policy" });
        Service service = service_Service.getServicePort(securityFeatures);
        Map reqContext = ((BindingProvider)service).getRequestContext();
        reqContext.put(BindingProvider.USERNAME_PROPERTY, "weblogic");
        reqContext.put(BindingProvider.PASSWORD_PROPERTY, "welcome1");
        service.salaryUpgrade("guo", convertToXMLGregorianCalendar(new Date()), 100, false);
    }
 
    public static XMLGregorianCalendar convertToXMLGregorianCalendar(Date date) {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTime(date);
        XMLGregorianCalendar gc = null;
        try {
            gc = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
        } catch (Exception e) {

            e.printStackTrace();
        }
        return gc;
    }
}

Project 下载:SampleWS(Security).7z

参考文献:
 1. http://blog.csdn.net/Jamse228/article/details/5666689
 2. https://blogs.oracle.com/shay/entry/accessing_secure_web_services_from

1 条评论:

Unknown 说...

Hi Thanks, Helped me a lot.