I've got a standalone on-premise Service Fabric Cluster that is secured using Windows Authentication.
In this application I have a ASP.NET Core WebApi Stateless service that tries to communicate with another stateless service via the remoting. Unfortunately I'm getting the following error when the WebApi service tries to RPC to the stateless service:
System.AggregateException: One or more errors occurred. ---> System.Fabric.FabricConnectionDeniedException: Not authorized to connect ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0x80071C43
at Microsoft.ServiceFabric.FabricTransport.NativeServiceCommunication.IFabricServiceCommunicationClient2.EndRequest(IFabricAsyncOperationContext context)
at Microsoft.ServiceFabric.FabricTransport.Client.FabricTransportClient.EndRequest(IFabricAsyncOperationContext context)
at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)
--- End of inner exception stack trace --
Futhermore, I can confirm that
When deploying this same application to a "development cluster" (i.e. either my local machine or another a remote Service Fabric cluster running all it's Nodes on one machine), I don't get the error - hence potentially an issue with the AD accounts I've used to setup my multi-machine cluster (I'm using a machine group account).
When creating the Client Proxy, I do setup the Security Credentials to use windows authentication - i.e.
var transportSettings = new FabricTransportRemotingSettings
{
SecurityCredentials = new WindowsCredentials()
};
Func<IServiceRemotingCallbackClient, IServiceRemotingClientFactory> clientProxyFactory = c => new FabricTransportServiceRemotingClientFactory(transportSettings);
var serviceProxyFactory = new ServiceProxyFactory(clientProxyFactory);
TService clientProxy = serviceProxyFactory.CreateServiceProxy<TService>(uri);
return clientProxy;
In the above code, if I instead use:
SecurityCredentials = new NoneSecurityCredentials() then I get a similar FabricConnectionDeniedException but the message is slightly different saying that the Client is not authorised to connect. This makes sense - but again, potentially indicates that there is an issue with my transport settings...
Related
I have an application that calls an ASMX web service which is situated on another server.
Recently, this server had been reconfigured to disable all TLS versions except for 1.3. This resulted in my application failing to call the ASMX with the following error:
Could not establish secure channel for SSL/TLS with authority '[website]'.
The application was compiled under .NET 4.5 which doesnt have an option to specify to use TLS 1.3. So i recompiled it under 4.8 with the relevant specification to use TLS1.3:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls13;
var basicHttpBinding = get_binding(); //returns either basicHTTpsBinding or basicHttpBinding
basicHttpBinding.MaxBufferPoolSize = maxBufferPoolSize;
basicHttpBinding.MaxBufferSize = maxBufferSize;
basicHttpBinding.MaxReceivedMessageSize = maxReceivedMessageSize;
String webServicesEndpointAddress = "url"
var endpointAddress = new EndpointAddress(webServicesEndpointAddress);
new ChannelFactory<customType>(basicHttpBinding, endpointAddress).CreateChannel();
var webServices = new webserviceSoapClient(basicHttpBinding, endpointAddress);
...
//code to call one of the web service functions
This however now results in a new error:
"An error occurred while receiving the HTTP response to [url] This could be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
enter code here
Any ideas what could be causing the above error? I am running the application locally in visual studio over windows 10
I'm playing with Azure Service Fabric and a console app. I simply want my console app to connect to the cluster and do some stuff.
The console app try to resolve the service address with the following:
static void Main(string[] args)
{
ServicePartitionResolver resolver = null;
try
{
resolver = new ServicePartitionResolver(
new string[] {
"localhost:19000",
"localhost:19001"
});
Uri serviceUri = new Uri("fabric:/StatefullServiceTEST/MyStatefulService");
ResolvedServicePartition partition = resolver.ResolveAsync(serviceUri, new ServicePartitionKey(), CancellationToken.None).GetAwaiter().GetResult();
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
Console.WriteLine();
Console.Write("Press any key to exit...");
Console.ReadKey();
}
My problem is that resolver.ResolveAsync throws an exception that doesn't seem to have any connection with Service Fabric:
Unable to cast COM object of type 'System.__ComObject' to interface
type 'IFabricApplicationManagementClient10'. This operation failed
because the QueryInterface call on the COM component for the interface
with IID '{67001225-D106-41AE-8BD4-5A0A119C5C01}' failed due to the
following error: No such interface supported (Exception from HRESULT:
0x80004002 (E_NOINTERFACE)).
Any ideas on this?
UPDATE
I was not so clear explaining my problem and what I want to achive.
I'm playing with Azure Service Fabric (both stateless and stateful services): my question is: what's the best way to call a micro service hosted in Azure Service Fabric?
Regards,
Attilio
You have to create a public facing service (such as Asp.net Core Web Api) which will expose the functionality of your service inside service fabric to outside world (outside the service fabric cluster). FabricClient approach is to be utilzied for calling services from within the service fabric cluster and not outside.
From your Asp.net Core service you will use the FabricClient to access the service hosted, so in general your asp.net core app act as reverse proxy to expose the functionality of actual service.
You can't use ServicePartitionResolver, it is a reliable service feature and must be called from within a service running in your cluster.
I couldn't understand clearly what you want.
If you want to manage the service and get details about it, like query running instances or replicas, add or remove instances, and so on, Use the Fabric Client, below is a quick snippet, check details here and here:
`
using System.Fabric;
using System.Security.Cryptography.X509Certificates;
string clientCertThumb = "71DE04467C9ED0544D021098BCD44C71E183414E";
string serverCertThumb = "A8136758F4AB8962AF2BF3F27921BE1DF67F4326";
string CommonName = "www.clustername.westus.azure.com";
string connection = "clustername.westus.cloudapp.azure.com:19000";
var xc = GetCredentials(clientCertThumb, serverCertThumb, CommonName);
var fc = new FabricClient(xc, connection);`
or,
If you want to communicate to a running service, like an API, you should use a Reverse Proxy to resolve your services via URL, like the below snippet, more details here:
http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService
You cannot access service in an ASF cluster from the outside using the ServicePartitionResolver.
You have to have a public facing endpoint on your cluster, like a stateless service acting as a web api for example.
From the docs:
Services connecting to each other inside a cluster generally can directly access the endpoints of other services because the nodes in a cluster are on the same local network. In some environments, however, a cluster may be behind a load balancer that routes external ingress traffic through a limited set of ports. In these cases, services can still communicate with each other and resolve addresses using the Naming Service, but extra steps must be taken to allow external clients to connect to services.
A Service Fabric cluster in Azure is placed behind an Azure Load Balancer. All external traffic to the cluster must pass through the load balancer. The load balancer will automatically forward traffic inbound on a given port to a random node that has the same port open. The Azure Load Balancer only knows about ports open on the nodes, it does not know about ports open by individual services.
So, unless your console app is hosted in the cluster as a guest executable, you have some more work to do.
I am new to Xamarin Forms. I am building an app which consumes a web service. I am getting HttpRequestException while trying to connect to server. The InnerException throws System.Net.WebException: Error: NameResolutionFailure at System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult).
The code that crash is:
public async Task<IEnumerable<Bono>> GetAll()
{
var Url = Constants.baseUrl + "cliente/1/bonos";
HttpClient cliente = new HttpClient();
var bonos = await cliente.GetStringAsync(Url);
return JsonConvert.DeserializeObject<List<Bono>>(bonos);
}
I am using VS for Mac. The same works for Xamarin.iOS. Any suggestion on this?
If the endpoint that you are trying to consume is hosted on your local machine and you are running the application in the local android emulator, you could use the following IP address to reach the host machine from the emulator:
http://10.0.2.2
Of course this will break iOS but it's the IP that can be used from an android emulator to access the host. As an alternative you could use ngrok which can create a publicly accessible tunnel to an endpoint hosted on your local machine and then access the public endpoint from the android application. It could be helpful during development if you want to avoid hosting your endpoint to a network location that can be accessed from the emulator.
I have an Azure Cloud Service with a worker role that starts an OWIN web app on startup, which uses SignalR.
Separately, I have a console project that uses the SignalR client library to connect to this worker role and listen for events.
Everything is working when I run the client and the service locally using the Azure emulators.
When I publish the cloud service and point the console application to it and try to connect, I get the following in the SignalR trace logs:
WS Connecting to: ws://myapp.cloudapp.net/signalr/connect?clientProtocol=1.4&transport=webSockets&connectionData=[{"Name":"MessageBusHub"}]&connectionToken=...
OnError(System.Net.WebSockets.WebSocketException (0x80004005): An internal WebSocket error occurred. Please see the innerException, if present, for more details. ---> System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
It then proceeds to try again using server sent events and long polling with the same error each time.
I'm using the following endpoint in my Cloud service config:
<Endpoints>
<InputEndpoint name="SignalREndpoint" protocol="http" port="80" localPort="80" />
</Endpoints>
And here is how I create my OWIN web app:
var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["SignalREndpoint"];
string webAppUrl = $"{endpoint.Protocol}://{endpoint.IPEndpoint}";
_webApp = WebApp.Start<Startup>(webAppUrl);
Finally, here's how I configure SignalR:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.UseServerAuthentication();
GlobalHost.DependencyResolver.UseServiceBus(CloudConfigurationManager.GetSetting("ServiceBusConnectionString"), "SignalRMessageBus");
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
});
}
}
In the client project I am simply using a HubConnection to connect using the following URL for local testing, http://localhost:80, and the following URL for connecting to the cloud instance, http://myapp.cloudapp.net
I'm not sure what's different between the actual Azure instance and my local emulator that's causing it to not work in the cloud.
Interestingly, if I use the browser to connect to the URL http://myapp.cloudapp.net/signalr/hubs, it works and returns the JS proxy file.
Have you tried using TCP instead of HTTP as a protocol?
I am not a SignalR expert in any way, but I know about it. When we host our server (XSockets.NET) on Azure worker roles we configure the protocol to be TCP (not HTTP).
Have no idea why it would work on localhost though.
Another thing to consider is if the worker role supports websockets? SignalR requires IIS8+ for websocket support and I have no idea if you have access to that in a worker role. There are no options in Azure to turn websockets on/off on a worker role (from what I can see). So my guess is that there is no Microsoft WebSockets in the worker role. By I might be wrong here!
EDIT: Looked at one of my instances and saw that I can change OS and that the default one is 2012 Server. So Microsoft websockets should be available!
Please bear with me as I am new to WCF services/ Windows services. I've created a WCF service hosted in a Windows service. I want to consume that WCF service in a Silverlight in-browser application over TCP. Below is the code fragment in Silverlight to access WCF service:
var messageEncoding = new BinaryMessageEncodingBindingElement();
var tcpTransport = new TcpTransportBindingElement();
var binding = new CustomBinding(messageEncoding, tcpTransport);
// Create a channel factory for the service endpoint configured with the custom binding.
var cf = new ChannelFactory<ICalcService>(binding, new EndpointAddress("net.tcp://192.168.2.104:4508"));
// Open the channel.
ICalcService channel = cf.CreateChannel();
// Invoke the method asynchronously.
channel.BeginAdd(9, 5, AddCallback, channel);
private void AddCallback(IAsyncResult asyncResult)
{
try
{
double endAdd = ((ICalcService) asyncResult.AsyncState).EndAdd(asyncResult);
}
catch (Exception exception)
{
throw exception;
}
}
The code works fine sometimes but often it throws an infamous System.ServiceModel.CommunicationException with the following message for some reasons:
Could not connect to net.tcp://192.168.2.104:4508/. The connection attempt lasted for a time span of 00:00:00.1010058. TCP error code 10013: An attempt was made to access a socket in a way forbidden by its access permissions.. This could be due to attempting to access a service in a cross-domain way while the service is not configured for cross-domain access. You may need to contact the owner of the service to expose a sockets cross-domain policy over HTTP and host the service in the allowed sockets port range 4502-4534.
The innerException of type System.Net.Sockets.SocketException says
An attempt was made to access a socket in a way forbidden by its access permissions.
What are the possible reasons behind this exceptions? Based on what I investigated so far, I could find only one reason: Improper ClientAccessPolicy.xml. What may be the other reasons? If you have any useful resources, please provide me the same. One more question, if I want to make Windows service hosted WCF service to get consumed by other machines on LAN, what settings do I have to make? E.g. firewall settings? My code cannot access WCF service on other machine. It throws the same exception I mentioned above. Any ideas about how to get rid of this exception?
Problem sorted..!! I had to do following things:
1) Specified SecurityMode.None while creating NetTcpBinding in Windows service.
2) Created an Inbound Rule in Windows Firewall With Advanced Security to allow TCP traffic on the port I specified in the end point address.