I stack on Apple GSX Api request in c# project. Everything is ok but I cannot get response from api.
Certificates done, Static IPs have whitelisted.
Return this error when i request to "https://gsxapiut.apple.com/gsx-ws/services/emea/asp"
{"An error occurred while making the HTTP request to
https://gsxapiut.apple.com/gsx-ws/services/emea/asp. This could be due
to the fact that the server certificate is not configured properly
with HTTP.SYS in the HTTPS case. This could also be caused by a
mismatch of the security binding between the client and the server."}
Request Function :
public void Authenticate()
{
try
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
EndpointAddress endpoint = new EndpointAddress("https://gsxapiut.apple.com/gsx-ws/services/emea/asp");
var sslCertFilename = "test.p12";
var sslCertPassword ="xxxxx";
GsxApi3.GsxWSEmeaAspPortClient service = new GsxApi3.GsxWSEmeaAspPortClient();
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
service.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2(
sslCertFilename,
sslCertPassword, X509KeyStorageFlags.MachineKeySet);
var auth = new GsxApi3.authenticateRequestType()
{
languageCode = "EN",
serviceAccountNo = "xxxxxxxxx",
userId = "xxxxxxxxxxx",
userTimeZone = "CET"
};
var session = service.Authenticate(auth);
var userSessionId = new GsxApi3.gsxUserSessionType { userSessionId = session.userSessionId };
}
catch (Exception err)
{
}
}
Related
I am trying to establish connection to external PKI SOAP web service, but not sure how to set BasicHttpBinding security in .NET 6. Constantly getting exception:
*System.ServiceModel.ProtocolException: 'The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding. '
*
I am using auto generated class from wsdl, but create my own binding.
BasicHttpBinding:
public BasicHttpBinding GetCustomBinding()
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)
{
Security =
{
Message =
{
ClientCredentialType = BasicHttpMessageCredentialType.Certificate
},
Transport =
{
ClientCredentialType = HttpClientCredentialType.Certificate
},
Mode = BasicHttpSecurityMode.Transport
},
MaxReceivedMessageSize = MaxMessageSizeBytes
};
return binding;
}
Creating proxy client:
public autoGeneratedClient GetClient(string endpointUrl, string dnsIdentity, string clientCertificatePath, string clientCertificatePassword, string serviceCertificatePath, int timeout = 10)
{
DnsEndpointIdentity endpointIdentity = new DnsEndpointIdentity(dnsIdentity);
EndpointAddress endpointAddress = new EndpointAddress(new Uri(endpointUrl), endpointIdentity);
//CustomBinding for eBox web service with security setup
MyCustomBinding myCustomBinding = new MyCustomBinding();
Binding binding = myCustomBinding.GetCustomBinding();
binding.CloseTimeout = new TimeSpan(0, timeout, 0);
binding.ReceiveTimeout = new TimeSpan(0, timeout, 0);
binding.SendTimeout = new TimeSpan(0, timeout, 0);
binding.OpenTimeout = new TimeSpan(0, timeout, 0);
autoGeneratedClient client = new autoGeneratedClient(binding, endpointAddress);
client.ClientCredentials.ClientCertificate.Certificate = X509CertificateFactory.GetClientCertificate(clientCertificatePath, clientCertificatePassword);
client.ClientCredentials.ServiceCertificate.DefaultCertificate = X509CertificateFactory.GetServiceCertificate(serviceCertificatePath);
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
return client;
}
I'm trying to access a REST service in a WCF server from power BI using Windows Authentication.
Currently the web request from Power BI is done to a nodejs server where we can get the NTLM authentication data in the 'authorization' header of the request.
But I need to do the same request on a WCF server instead. The Rest service of the WCF is working well, when not using any authentication I can access it with the power BI request through https without any issue.
But when I activate the authentication in the WCF server (with binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows), the request is rejected because the authentication fails. I cannot even use the NTLM data as the 'authentication' field in header is not in the received request (when authentication is not set, but I assume that's normal).
For now, everything is running on my machine, and I'm using the "Use my current credentials" option when doing the Windows authentication in Power BI. OF course there's an Active Directory.
the code in the WCF server:
private void StartRestServiceHosts(int port)
{
try
{
using (ServerContainerScope containerScope = new ServerContainerScope())
{
RequestContext.Current.Initialize(LogAreas.Server, Shared.MainUserLogin);
string protocol = Shared.HttpsEnabled ? "https" : "http";
string uri = string.Format("{0}://{1}:{2}/Rest/", protocol, System.Environment.MachineName, port);
Uri httpBaseAddress = new Uri(uri);
var defaultWebHttpBehavior = new WebHttpBehavior()
{
AutomaticFormatSelectionEnabled = true,
DefaultBodyStyle = WebMessageBodyStyle.Wrapped,
DefaultOutgoingRequestFormat = WebMessageFormat.Json,
DefaultOutgoingResponseFormat = WebMessageFormat.Json,
HelpEnabled = false
};
foreach (ServiceDefinition serviceDefinition in _registeredRestServices.Values)
{
string currentServiceName = serviceDefinition.Name;
if (!_restServiceHosts.ContainsKey(currentServiceName))
{
ServiceHost host = new ServiceHost(serviceDefinition.Type,
new Uri(httpBaseAddress, serviceDefinition.Type.Name));
host.Authorization.ServiceAuthorizationManager = new PublicAuthorization();
Type contract = serviceDefinition.Type.GetInterface("I" + serviceDefinition.Type.Name);
ServiceEndpoint endPoint = new ServiceEndpoint(
ContractDescription.GetContract(contract),
_restBinding,
new EndpointAddress("{0}{1}".FormatWith(uri, contract.Name))
);
endPoint.Behaviors.Add(defaultWebHttpBehavior);
endPoint.Behaviors.Add(new CorsSupportBehavior());
host.AddServiceEndpoint(endPoint);
_restServiceHosts.Add(currentServiceName, host);
}
// Open
if (_restServiceHosts[currentServiceName].State != CommunicationState.Opened)
{
_restServiceHosts[currentServiceName].Open();
}
}
OnWcfRestServicesStarted?.Invoke(null, true);
}
}
catch (Exception ex)
{
OnWcfRestServicesStarted?.Invoke(null, false);
}
}
public WebHttpBinding CreateWebHttpBinding(string name)
{
WebHttpBinding binding = new WebHttpBinding();
binding.Security.Mode = Shared.HttpsEnabled ? WebHttpSecurityMode.Transport : WebHttpSecurityMode.None;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
//binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
binding.Name = name;
binding.ReceiveTimeout = new TimeSpan(1, 0, 0);
binding.MaxBufferSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
return binding;
}
<appSettings>
<add key="HttpsEnabled" value="true"/>
</appSettings>
Any ideas as to why the authentication is not working?
Thanks in advance!!!
I try to call a SOAP service by authenticating myself with a SAML token.
First I get a SAML token for the target by calling the ADFS:
var stsEndpoint = "https://ADFS.EXAMPLE/adfs/services/trust/13/kerberosmixed";
var reliantPartyUri = "http://reliant-party.com";
var binding = new CustomBinding();
var ssbe = SecurityBindingElement.CreateKerberosOverTransportBindingElement();
ssbe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
ssbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
binding.Elements.Add(ssbe);
binding.Elements.Add(new TextMessageEncodingBindingElement());
binding.Elements.Add(new HttpsTransportBindingElement());
var factory = new WSTrustChannelFactory(binding, new EndpointAddress(stsEndpoint));
factory.TrustVersion = TrustVersion.WSTrust13;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference(reliantPartyUri)
};
var channel = factory.CreateChannel();
var token = channel.Issue(rst);
Now I want to use the SAML token to call a secured SOAP webservice. How is it possible to add the token? I've tried the following without success (the soap request does not contain any token):
//Service was created by an imported WSDL File - Methods and Types renamed for StackOverflow
var request = new Service.WsdlCreatedRequest();
[...]
var wsdlClient = new Service.WsdlCreatedService("HTTPS_Port");
var wsdlChannel = wsdlClient.ChannelFactory.CreateChannelWithIssuedToken(token);
wsdlChannel.WsdlCreatedMethod(request);
Any idea how to use the token in the request?
How do I generate a SAML token without using credentials again?
Scenario: I am trying to send a SAML token to SAP web service. Since multiple users will be using this application I do not want to ask them for credentials but instead get them from current machine windows credentials and generate a SAML token.
This is what is currently being used in my code.
factory.Credentials.UserName.UserName = "bob";
factory.Credentials.UserName.Password = "abc!123";
// create token request
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
KeyType = KeyTypes.Symmetric,
AppliesTo = new EndpointReference(_serviceAddress.AbsoluteUri)
};
I use this method in my code to pass through the credentials of the logged in user to our ADFS server for single-sign in to O365 from the applications I write; you might be able to adapt the code to suit your purposes:
private GenericXmlSecurityToken NewGetAdfsSamlTokenWinAuth()
{
try
{
WS2007HttpBinding binding = new WS2007HttpBinding(SecurityMode.Transport);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
WSTrustChannelFactory factory = new WSTrustChannelFactory((binding), new EndpointAddress(this.adfsIntegratedAuthUrl));
factory.TrustVersion = TrustVersion.WSTrustFeb2005;
factory.Credentials.SupportInteractive = false;
var rst = new RequestSecurityToken
{
RequestType = RequestTypes.Issue,
AppliesTo = new EndpointReference("urn:federation:MicrosoftOnline"),
KeyType = KeyTypes.Bearer
};
IWSTrustChannelContract channel = factory.CreateChannel();
return channel.Issue(rst) as GenericXmlSecurityToken;
}
catch (Exception ex)
{
// Do something with the exception
}
return null;
}
This will return a GenericXmlSecurityToken which has a TokenXml.OuterXml property that contains the SAML assertion.
I have the following bit of code to make a call to the
YouTubeService service = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = AppSettings.Variables.YouTube_APIKey,
ApplicationName = AppSettings.Variables.YouTube_AppName
});
Google.Apis.YouTube.v3.VideosResource.ListRequest request = service.Videos.List("snippet,statistics");
request.Id = string.Join(",", videoIDs);
VideoListResponse response = request.Execute();
This all works but when we deploy it to our live server, it needs to get through a proxy so we put the following into the web.config:
<defaultProxy useDefaultCredentials="false" enabled="true">
<proxy usesystemdefault="False" proxyaddress="http://192.111.111.102:8081" />
</defaultProxy>
However, this doesn't seem to be working as when the call is made, I get the following error:
System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 216.58.213.74:443
Is there a way to manually set the proxy in code?
Something along the lines of:
WebProxy proxy = new WebProxy("192.111.111.102", 8081);
proxy.Credentials = new NetworkCredential(AppSettings.Variables.ProxyUser, AppSettings.Variables.ProxyPassword, AppSettings.Variables.ProxyDomain);
// apply this to the service or request object here
Yes of course!
You can set a System.Net.WebProxy for a YouTubeService instance:
var _youtubeService = new YouTubeService(yourInitializer);
_youtubeService.HttpClient.MessageHandler.InnerHandler = new HttpClientHandler
{
Proxy = new WebProxy(your parameters..)
};
NOTE : Don't forget to set other HttpClientHandler properties if needed(for example AutomaticDecompression)
To get around this I had to make a webrequest to the url and map the result back to the VideoListResponse object:
try
{
Uri api = new Uri(string.Format("https://www.googleapis.com/youtube/v3/videos?id={0}&key={1}&part=snippet,statistics", videoIds, AppSettings.Variables.YouTube_APIKey));
WebRequest request = WebRequest.Create(api);
WebProxy proxy = new WebProxy(AppSettings.Variables.ProxyAddress, AppSettings.Variables.ProxyPort);
proxy.Credentials = new NetworkCredential(AppSettings.Variables.ProxyUsername, AppSettings.Variables.ProxyPassword, AppSettings.Variables.ProxyDomain);
request.Proxy = proxy;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
{
return JsonConvert.DeserializeObject<VideoListResponse>(streamReader.ReadToEnd());
}
}
}
catch (Exception ex)
{
ErrorLog.LogError(ex, "Video entity processing error: ");
}
The solution of #ABS looks more efficient and "compact" to me.
Here's how i use it in VB.NET with the Youtube Channel API:
Dim uriProxy As New Uri("*proxy_url:IP*")
Dim wpyProxy As New WebProxy With {.Address = uriProxy }
Dim get_youtube_channel_channel_work As New youtube_channel
Dim youtube_initialiser As New Google.Apis.Services.BaseClientService.Initializer()
youtube_initialiser.ApiKey = ConfigurationManager.AppSettings("youtube_api_key")
youtube_initialiser.ApplicationName = ConfigurationManager.AppSettings("youtube_api_application_name")
Dim youtube_service As Google.Apis.YouTube.v3.YouTubeService = New YouTubeService(youtube_initialiser)
Dim objChannelListRequest As ChannelsResource.ListRequest = youtube_service.Channels.List("id, snippet, statistics")
youtube_service.HttpClient.MessageHandler.InnerHandler = New HttpClientHandler With {.Proxy = wpyProxy}