This article explains how to configure NTLM protected web Service from the SOA 11g ,
This contains all the steps required to configure a Active Directory , DNS Server and NTLM based Web Service and integrating with SOA 11g etc.
As the setup needs lot of manual setup's I documented all the important steps so that you will not be wasting much time like I did in this case ,
Important points :-
Create a AD Domain first , make sure you select the DNS Server part of this AD Setup , if you do not select this step then NTLM may not work properly.
You can use the tool , dcpromo for this purpose ,
Refer to this blog for the Active Directory Install ,
http://helpdeskgeek.com/how-to/windows-2003-active-directory-setupdcpromo/
Open the DNS Server Setup on the Windows 2003 machine and put your actual DNS machine as forward DNS to this DNS Sever.
And Add the DNS Servers To the list ,
and restart the Windows 2003 domain ,
Now login in to the test Windows XP machine
In the DNS Server specificy the your Active Directory Machine name , As you have to setup your main DNS Server
as the forward DNS in the Windows 2003 , you will not have any problems in accessing the other machines in your setup.
Go to My Computer Properties and use the AD Domain machine , for example ,
Create a test user from Windows 2003 domain and use this user to login to Windows 2003 domain , for example
Now install the IIS Server on the Windows 2003 machine , Click on Add or Remove programs and Add/Remove Windows Components
Install .Net FrameWork SDK , i.e .NET 4.0.X on this machine ,
Invoke the inetmgr (IIS Admin tool ) and Create a Virtual Directory say c:\temp\test1
Under Directory Server for this Virtual Directory remove the Enable Anonymous access and click
on Integrated Windows Authentication ,
Create a Simple HTML File with the following on this ,
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<title>Test Page IIS</title>
</head>
<body>
Hello Test<br>
</body>
</html>
Access the URL using ,
http://iscsoavm10.mydomain.com/test1/test.html
This asks for a username and password on a plain machine ,
If you access this URL using a machine , that is already logged in to this domain , then it will not ask for the password. This is what NTLM about.
For testing the ASP.Net file create the following test.aspx file ,
<%@ Page Language="C#" %>
<html>
<head>
<title>ASP.NET Hello World</title>
</head>
<body bgcolor="#FFFFFF">
<p><%= "Hello World!" %></p>
<p><%= User.Identity.Name %></p>
</body>
</html>
Copy this file in c:\temp\test1 directory and run the
http://iscsoavm10.mydomain.com/test1/test.aspx
This displays the o/p as
Hello World!
ISCSOAVM100\Administrator
Using Visual C# Studio create a Sample Web Service
In the Web.config file have the following entries ,
==========================================================================================
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<compilation>
</compilation>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<authentication mode="Windows" />
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm"/>
<error statusCode="404" redirect="FileNotFound.htm"/>
</customErrors>
-->
</system.web>
<system.webServer>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
<system.serviceModel>
<services>
<service name="WcfService3.Service1" behaviorConfiguration="WcfService3.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="WcfService3.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="basicHttpBinding" contract="IMetadataExchange" bindingConfiguration="BasicHttpEndpointBinding" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService3.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
==========================================================================================
The important one's are
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="WcfService3.IService1">
<endpoint address="mex" binding="basicHttpBinding" contract="IMetadataExchange" bindingConfiguration="BasicHttpEndpointBinding" />
With out this , you may get lot of exceptions like 'anonymous' users are not allowed etc ,
Web Service Code
---------------------
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Web;
using System.ServiceModel;
namespace WcfService3
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
public string GetData( int value)
{
// OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
// Create stream writer object and pass it the file path
StringBuilder sw = new StringBuilder ();
sw.AppendLine( "--------> " + value);
return string.Format( "You entered: {0}", sw.ToString());
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite" );
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
Web Services Interface Code
===========================
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService3
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[ OperationContract]
string GetData( int value);
[ OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[ DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[ DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
}
From Visual Studio Create a New Publish Profile with the directory as say c:\temp\test
and publish this Web Service to this directory.
If the C# Visual studio and IIS server are there on a different machines then copy the contents c:\temp\test to the IIS Server directory.
From the Browser access the URL ,
http://iscsoavm10.mydomain.com/test1/Service1.svc
This should ask for a password, enter the username as test and Welcome1.
Now from SOAP UI
Click on Auth from the SOAP UI
From JDeveloper you have to first download the wsdl file and the related XSD files manually ,
First download the wsdl file ,
http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?wsdl
In this wsdl file , you will find you need 3 xsd files ,
<xsd:import schemaLocation="http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/WcfService3"/>
Download the xsd files ,
http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd0 as xsd0.xsd
http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd1 as xsd1.xsd
http://iscsoavm10.iscsoavm10.mydomain.com/Test1/Service1.svc?xsd=xsd2 as xsd2.xsd
and change the downloaded wsdl file
<xsd:import schemaLocation="xsd/xsd0.xsd" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="xsd/xsd2.xsd" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="xsd/xsd2.xsd" namespace="http://schemas.datacontract.org/2004/07/WcfService3"/>
And create a simple BPEL to call this service ,
In the composite.xml file have the following entries ,
oracle.webservices.auth.username
oracle.webservices.auth.password
oracle.webservices.preemptiveBasicAuth as false ,
for example ,
<binding.ws port="http://tempuri.org/#wsdl.endpoint(Service1/BasicHttpBinding_IService1)"
location="test1.wsdl" soapVersion="1.1">
<property name="weblogic.wsee.wsat.transaction.flowOption"
type="xs:string" many="false">WSDLDriven</property>
<property name="oracle.webservices.auth.username" type="xs:string" many="false">test</property>
<property name="oracle.webservices.auth.password" type="xs:string" many="false">Welcome1</property>
<property name="oracle.webservices.preemptiveBasicAuth" type="xs:string" many="false">false</property>
</binding.ws>
You can also set these properties from EM Console ,
Click on your SOA project , and Services and References
and Click on Web Service you are calling and Click on the Proprties TAB , here you can enter the values for
oracle.webservices.auth.username
oracle.webservices.auth.password
oracle.webservices.preemptiveBasicAuth