Reputation: 31
I'm trying to consume a third-party web service (discription on russian language) https://92.46.122.150:8443/esf-web/ws/SessionService?wsdl
I am trying to connect to a website using method "createSession", get Id session and close session in a website. Do this I using Visual Studio 2013, C#, .NET 4.5, WSE 3.0 (Microsoft.Web.Services3.dll).
I have already created project in Visual Studio 2013 "Windows Forms Application". In this form user can enter user name, login and to choose his a digital signature certificate. Also I added web service as a "web service reference" but I'm not sure how to pass the credentials for the header.
I'm trying to do this:
string strPasswordCertificate = "123456";
string strCertificate = "C:/Test/AUTH_RSA_db79bb07b4722c042e025979b3b11995fc46765b.p12";
X509Certificate x509_CertAUTH = new X509Certificate(strCertificateFilePathAUTH, strPasswordCertificate);
string strCertAUTH = x509_CertAUTH.ToString();
CreateSessionRequest CreateReq = new CreateSessionRequest();
CreateReq.x509Certificate = strCertAUTH;
string strIIN = "753159846249";
CreateReq.tin = strIIN;
WS.createSession(CreateReq);
But when run a programm Visual studio show an error on a line with "WS.createSession(CreateReq)" like below:
SoapHeaderException was unhandled. An unhandled exception of type "System.Web.Service.Protocols.SoapHeaderExeption" occurred in System.Web.Services.dll Additional information: An error was discovered processing the "wsse:Security" header.
This exception is thrown when an XML Web service method is called over SOAP and an exception occurs during processing of the SOAP header. After that I made changes in my code like below:
string strPasswordCertificate = "123456";
string strCertificate = "C:/Test/AUTH_RSA_db79bb07b4722c042e025979b3b11995fc46765b.p12";
X509Certificate x509_CertAUTH = new X509Certificate(strCertificateFilePathAUTH, strPasswordCertificate);
string strCertAUTH = x509_CertAUTH.ToString();
CreateSessionRequest CreateReq = new CreateSessionRequest();
CreateReq.x509Certificate = strCertAUTH;
string strIIN = "753159846249";
CreateReq.tin = strIIN;
WS.createSession(CreateReq);
string _userName = "123456789011";
string _UserPassword = "TestPass123";
UsernameToken userToken;
userToken = new UsernameToken(_userName, _UserPassword, PasswordOption.SendPlainText);
SessionService WS = new SessionService();
SoapContext requestContext = WS.RequestSoapContext;
requestContext.Security.Tokens.Add(userToken);
WS.createSession(CreateReq);
But when run a programm Visual studio show error on a line with "WS.createSession(CreateReq)" like below:
SoapHeaderException was unhandled. An unhandled exception of type 'System.Web.Service.Protocols.SoapHeaderExeption' occurred in System.Web.Services.dll Additional information: An invalid security token was provided.
What I need more to do or change in my code that web reverence start to work? Any idea?
Upvotes: 0
Views: 1186
Reputation: 31
First, need add web service "https://92.46.122.150:8443/esf-web/ws/SessionService?wsdl" like Service Reference.
Second, your certificate should be like trusted. If not, then you can do this using code below:
System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Third, add in your solution new item like C# class for your SOAP header. In this class shoud be code like below:
namespace WindowsFormsApplication1
{
public class MySoapSecurityHeader : MessageHeader
{
private readonly UsernameToken _usernameToken;
public MySoapSecurityHeader(string username, string password)
{
_usernameToken = new UsernameToken(string.Empty, username, password);
}
public MySoapSecurityHeader(string id, string username, string password)
{
_usernameToken = new UsernameToken(id, username, password);
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
XmlSerializer serializer = new XmlSerializer(typeof(UsernameToken));
serializer.Serialize(writer, _usernameToken);
}
}
[XmlRoot(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")]
public class UsernameToken
{
public UsernameToken()
{
}
public UsernameToken(string id, string username, string password)
{
Id = id;
Username = username;
Password = new Password() { Value = password };
}
[XmlAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")]
public string Id { get; set; }
[XmlElement]
public string Username { get; set; }
[XmlElement]
public Password Password { get; set; }
}
public class Password
{
public Password()
{
Type = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
}
[XmlAttribute]
public string Type { get; set; }
[XmlText]
public string Value { get; set; }
}
}
After that you need add code in a file "Form1.cs":
//The path to the certificate.
string certPath = "C:/AUTH_RSA256_e9f5afab50193175883774ec07bac05cb8c9e2d7.p12";
//Password to signing a certificate
string certPassword = "123456";
//IIN or BIN persom who signing ESF on esf_gov site
var tin = "123456789021";
//Load the certificate into an X509Certificate object.
X509Certificate x509Cert = new X509Certificate(certPath, certPassword);
//Transfer sertificate to string value of base64
var certPEM = ExportToPEM(x509Cert);
using (SessionServiceClient client = new SessionServiceClient())
{
using (new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(
new MySoapSecurityHeader("123456789011", "TestPass123"));
//Create session for a work with site ESF
CreateSessionRequest createSessionRequest = new CreateSessionRequest
{
tin = tin,
x509Certificate = certPEM
};
var response = client.createSession(createSessionRequest);
MessageBox.Show("Session ID is: " + response.sessionId, "Information message",
MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
//Close session for a work with site ESF
CloseSessionRequest closeSessionRequest = new CloseSessionRequest
{
sessionId = response.sessionId,
tin = tin,
x509Certificate = certPEM
};
var closeResponse = client.closeSession(closeSessionRequest);
}
}
}
public static string ExportToPEM(X509Certificate cert)
{
//Export certificate, get baty array, convert in base64 string
return Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks);
}
Then run a programm and this will be work.
Upvotes: 2