I have an extremely basic API set up on my IIS. I'm doing nothing with the code yet:
public class RESTAPIController : ApiController
{
// GET: api/RESTAPI
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET: api/RESTAPI/5
public string Get(int id)
{
return "value";
}
// POST: api/RESTAPI
public void Post([FromBody]string value)
{
}
// PUT: api/RESTAPI/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE: api/RESTAPI/5
public void Delete(int id)
{
}
}
What I need to do is be able to POST/GET to this API from another computer on the same network. I can POST/GET/etc. on my own computer using the YARC Google Chrome extension. If I am debugging the API from Visual Studio, the breakpoint hits letting me know that it's working, I also get the 200 response back.
I'd like to be able to POST/GET to this API from another computer that lives on the same network. I always get a connection timeout error. The URL seen in the YARC app photo uses http://172.16.1.132:100/RestAPI/api/RESTAPI where "172.16.1.132" is my PC's ethernet port ip address for the port I am connected to. ":100" is the port that I have bound in IIS, ":80" could also be used. "RestAPI" is the name of the API that I am trying to call and "api/RESTAPI" is how to call the POST/GET method.
I've tried:
Completely disabling my firewall and Windows Defender;
Disabling the firewall on my router;
various configurations of the URL (different ports/authentication types/etc).
I'm very new to web apps and networking and I'm not even sure if what I am trying to do is possible. Any help is greatly appreciated. Thanks in advance!
Use iisexpress-proxy - A simple local proxy for accessing IIS Express from remote machines.
Open command prompt as administrator and run
npm install -g iisexpress-proxy
then
iisexpress-proxy 100 to 81 (100 - localPort and 81 proxyPort)
Access the API using this address on the other PC http://172.16.1.132:81/RestAPI/api/RESTAPI
Note: instead of 81 any other unused port can also be taken.
Related
I have a .NET MVC application which has multiple features.
Can I host this application in IIS as single application by configuring different ports as shown below?
Website to view product localhost:80/index.cs
API exposed for internal usage localhost:23004/Listporducts();
Is it possible?
Real time scenario: I am hosting application in Azure IaaS VM. My internal applications will use the API and customers shall use public website
In my opinion, the most easily thing is you could prevent the Azure VM's not open the 23004 port. Details, you could refer to this article.
If you don't want to use Azure MV, you could consider using a custom filter Attribute in the web api to check if the request is local. If the request is not sent from local, then you could directly return the 404 not found error.
More details about how to use custom Filter Attribute, you could refer to this article.
public class CustomActionAttribute : FilterAttribute, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
if (filterContext.HttpContext.Request.IsLocal) {
filterContext.Result = new HttpNotFoundResult();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext) {
// not yet implemented
}
}
My company has a variety of software products which have the ability to record an IP address. Each product does this differently, be it via HttpContext.Request.UserHostAddress or some sort of server variable (HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, or REMOTE_ADDR) or one or two other ways.
We recently moved data centers, and our 3 web servers are in a load balancer. Most of these solutions now record the load balancer's IP address instead of the actual end user's IP. According to my research, the HTTP_X_FORWARDED_FOR should give us the desired IP (once we configure IIS / the load balancer correctly).
I created a DLL which I'd like to plug into the rest of our applications:
using System.Web.Mvc;
namespace MyIpReader
{
public class IpReader : Controller
{
public string GetXForwardIp()
{
if (Request == null || Request.ServerVariables["HTTP_X_FORWARDED_FOR"] == null)
return System.Web.HttpContext.Current.Request.UserHostAddress;
return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
}
}
}
I added this DLL to one of our projects and run it, but the Request object is always null so it ends up returning the UserHostAddress.
Why is this, and more importantly how can I fix it?
If it matters: my MyIpReader project is .NET 4.5 and the System.Web.Mvc DLL says Runtime Version v4.0.30319 and the actual Version property itself is 5.2.3.0
Request must be evaluated in the context of the web request.
I sueest you this solution:
namespace MyIpReader
{
public class IpReader : Controller
{
private string HttpRequest request;
public IpReader(HttpRequest request)
{
this.request = request;
}
public string GetXForwardIp()
{
if (this.request == null || this.request.ServerVariables["HTTP_X_FORWARDED_FOR"] == null)
return System.Web.HttpContext.Current.Request.UserHostAddress;
return this.request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
}
}
}
I figured this question might have been asked before, but I have found no success implementation yet, so that prompted me to ask a new one.
My scenario is looking like this: I have one server (running under an ASP.Net site). A main SignalR server is self-hosted within the application using OWIN. Let's say this is running under localhost:8181. I have one central Hub that contains all the necessary functions to communicate between the client and the server itself. Under normal usage, the client would make a call to this endpoint: http://localhost:8181/signalr/hubs.
Now, I would like to add another different endpoint of SignalR, like http://localhost:8282/signalr2/hubs. The reason is that, in the central Hub, I have a function that only used by a specific client. The special client is the only client that I want to be able to invoke that function and within it, the data is transferred to other clients in the first endpoints. In theory, I could make use one endpoint and manage them, but I would like to separate out the special client for easy debugging and maintenance, as well as maybe performance improvement.
Right now, I can start them both using different configurations in the same ASP.Net application. Connections from all clients, including the special client are working. Except, at this point, I do not know a good way to filter the special client and send the data to other clients.
Below is the configuration code for both endpoints that I have implemented:
public class SignalRStartup
{
public void Configuration(IAppBuilder app)
{
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
};
app.UseCors(CorsOptions.AllowAll);
app.UseErrorPage(new Microsoft.Owin.Diagnostics.ErrorPageOptions { ShowExceptionDetails = true });
app.MapSignalR(hubConfiguration);
}
}
public class SignalR2Startup
{
public void Configuration(IAppBuilder app)
{
var hubConfiguration = new HubConfiguration
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true,
};
app.UseCors(CorsOptions.AllowAll);
app.UseErrorPage(new Microsoft.Owin.Diagnostics.ErrorPageOptions { ShowExceptionDetails = true });
app.MapSignalR("/signalr2", hubConfiguration);
}
}
In the Application_Start(), I added these:
_signalR = WebApp.Start<SignalRStartup>("http://localhost:8181");
_signalR2 = WebApp.Start<SignalR2Startup>("http://localhost:8282");
Sample Hub code:
[HubName("NotificationHub")]
public class NotificationHub : Hub
{
// Special client invoke this, the msg is passed to other clients in the 8181 endpoint
public void A(string msg)
{
// This Clients object should refer to other clients in 8181 endpoint
Clients.All.sendMsg(msg);
}
}
Because of the Clients is resolved automatically by GlobalHost, that means its include all the client, without any exception.
So my question is that what is the correct implementation in order to achieve my scenario? Also, if we use the proper implementation, how to figure out the correct clients so send the message that can exclude the ?
To summarize:
SignalR 1 & SignalR 2 has same NotificationHub with function A
Client 1 -> SignalR 1 (localhost:8181)
Client 2 -> SignalR 1 (localhost:8181)
SpecialClient -> Signalr 2 (localhost:8282)
SpecialClient invoke A(), in which, data is send to Client 1 & Client 2, exclude SpecialClient
The special client is the only client that I want to be able to invoke
that function and within it, the data is transferred to other clients
The easiest way is to not separate them.
In some manner you have to know what makes that client "special" and with that you can put them in a role to give them access to methods other clients cannot access.
Restrict access to certain methods -
[Authorize(Roles = "Admin")]
public class AdminAuthHub : Hub
{
}
Find more info - https://learn.microsoft.com/en-us/aspnet/signalr/overview/security/hub-authorization
How to send data to the clients -> Clients.Others would send to everyone else except the sender (the special client). But you could also put your special client in a "special" group and all your other clients in "non-special" group and only broadcast to the group you want using Clients.Group
I wanwt to add a layer of security via certificate to access a hosted ASP.NET WebAPI.
I want only those clients who have installed the certificate in their machine to have access to that WebAPI.
Can anyone provide me a way to achieve this behavior?
You can configure IIS to require client certificates without writing a single line of code. Just follow these instructions, specifically these:
Click SSL settings in the middle panel and select Require SSL and Require for Client certificates.
Double click the Authentication icon and disable all the Authentication method.
Make sure the IIS Client Certificate Mapping Authentication is installed.
Click the Configuration Editor in the middle panel and set the one to one mappings refer to this link
Just as suggested in comments, a quick google search could lead to interesting results.
Nevertheless a possible solution is the implementation proposed in the following Microsoft article :
public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
}
You would then decorate your ApiController action :
public class SomeController : ApiController
{
[RequireHttps]
public HttpResponseMessage Get() { ... }
}
I'm creating a web dashboard that will display the status of our test environments.
I use a hub to connect the browser to the server and have a background task that polls the status of the environment. I only want to perform this check if at least one client is connected.
My hub looks a little like this:
public class StatusHub : Hub
{
private static int connectionCount = 0;
public override Task OnConnected()
{
Interlocked.Increment(ref connectionCount);
return base.OnConnected();
}
public override Task OnReconnected()
{
Interlocked.Increment(ref connectionCount);
return base.OnReconnected();
}
public override Task OnDisconnected()
{
Interlocked.Decrement(ref connectionCount);
return base.OnDisconnected();
}
// other useful stuff
}
This mainly works but sometimes OnConnected is called but OnDisconnected is not.
One specific case is if I open chrome and type the address of the page but don't actually navigate to it. It seems Chrome is pre-fetching the page and connecting, but never disconnecting.
So two questions:
Is this a good approach to counting connections (I'm never going to be running in a web farm environment)?
Will these zombied connections from Chrome eventually timeout (I tried setting timeouts very low but still didn't get a disconnect)?
The events will always fire. If they don't, file a bug with repro steps on github. To get a more accurate number, you can store a hashset of connection ids and get the count from that.