Get IP Address with Web API - c#

I'm currently using MVC4 web API and for one of the calls I need to get the client's IP address. Here is my setup...
Client computers have no internet access, only access to our intranet
since I am making cross domain calls, I have to iframe a web server page into the client HTML page and post a message.
Once the web server receives the message, it makes an ajax call to the RESTful service and C# takes it from there...
So my current goal is the get the IP address of the client machine. After some research, I found this...
private string GetClientIp(HttpRequestMessage request)
{
if (request.Properties.ContainsKey("MS_HttpContext"))
{
return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
}
else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
{
RemoteEndpointMessageProperty prop;
prop = (RemoteEndpointMessageProperty)this.Request.Properties[RemoteEndpointMessageProperty.Name];
return prop.Address;
}
else
{
return null;
}
Now I realize I'm not the smartest person, but what would I pass for the parameter of HTTPRequestMessage request?
private string GetClientIp(HttpRequestMessage request)
Is there an example of this? Is this possible? Or is there another approach I should take for this

Excuse the VB.NET but you could do this also:
Add to your Global.asax (this will include the current session in your Web Api Controller):
Private Shared Function IsWebApiRequest() As Boolean
Return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith("~/api")
End Function
Protected Sub Application_PostAuthorizeRequest()
If IsWebApiRequest() Then
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required)
End If
End Sub
Then in your Web API Controller:
Public Shared Function GetIPAddress() As String
Dim context As System.Web.HttpContext =
System.Web.HttpContext.Current
Dim sIPAddress As String =
context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If String.IsNullOrEmpty(sIPAddress) Then
Return context.Request.ServerVariables("REMOTE_ADDR")
Else
Dim ipArray As String() = sIPAddress.Split(
New [Char]() {","c})
Return ipArray(0)
End If
End Function
You will be breaking RESTful design with this but it is all about what works, people are too dogmatic about REST in regards to certain types of projects in my opinion anyways.

Related

How can I connect my front end to my individually created backend

I am a beginner in creating a code and I am trying to code using vue js for my front end and aspnet core for my backend (web api). There arent many references in creating a to do list with this two connected.
I have already individually set up my front end in vs code while my back end in c#. I am having a hard time in connecting this two as there is not much update reference. How can I call my backend and connect it to my vue js.
thank you!
The first thing you need to do is open the back end CORS settings.
It connects to an endpoint on the Vue side, you can use axios framework to pull data
Here is an example
https://www.freecodecamp.org/news/how-to-build-an-spa-with-vuejs-and-c-using-net-core/
All you need to do is call the backend via API. Get the data via GET method, send the data via POST method. Let's say you want to get person list from the backend. You can do this -
const response = await fetch('https://yourawesomebackend.com/api/person/getpeople');
const content = await response.json();
// Now manipulate the DOM with the response.
In your backend, you might want to do this -
[Route("api/[controller]/[action]")]
[ApiController]
public class PersonController : ControllerBase
{
public IActionResult GetPeople()
{
// read people from database
var people = getFromDatabase();
return Ok(people);
}
}
Hope this helps.

Xamarin Forms SOAP WebService, how to get data?

I have searched for a few days now and cannot figure this out. I would like to get my results from a WebService. I am using PCL and as far as I can tell we cannot use string as a variable when returning, only void.
WebServiceSoapClient client = new WebServiceSoapClient();
string result = client.SetDriverAvailAsync(varUserid, varPassword, varLocation, varDateTime);
Above is what I'm using to call the method. And the web service was written as such.
[WebMethod]
public string SetDriverAvail(string drivername, string password, string location, string datetime)
{
if (location == "" || datetime == "")
{
return "failed";
}
It does a bunch of other stuff. Then returns "success" or "failed". Bottom line is. When i make my Service Reference for a Portable Form in Xamarin the only methods it makes in the Connection Service are public voids.
If I make a Service Reference in all other projects like ASP Web Page, ect. It builds these methods differently. And does let you return a string.
CONFUSED ... THANKS
This may be a simplistic answer, but I suggest you read Xamarin introduction to web services

Token based security for a web service

I am coding a C# web service using web API 2 where some of the CRUD actions need to have some security based off of a user's subscription.
Each user has a unique string token as part of their subscription.
Before I write my code for the webservice security, can someone please inform me if the following is a safe and efficient technique, and if not, why this is not safe and efficient and some other ways to accomplish this task.
I am thinking as part of each webservice request, a string parameter with the user's token is included. This token is then used to ensure that the user making the request owns the object.
Here is an example of a current function with no security:
[System.Web.Http.HttpGet]
[Route("Getdata/{id:int}")]
[ResponseType(typeof(Data))]
public async Task<IHttpActionResult> GetData(int id)
{
Data data = await dbSetService.Get(id);
if (data == null)
{
return NotFound();
}
return Ok(data);
}
Here is an example of a function with the token based security:
[System.Web.Http.HttpGet]
[Route("Getdata/{string:token},{id:int}")]
[ResponseType(typeof(Data))]
public async Task<IHttpActionResult> GetData(string token, int id)
{
Data data = await dbSetService.Get(id);
if (data == null)
{
return NotFound();
}
//Check if the owner of the data object has the correct token, and the object is returned if the token is correct
return Ok(data);
}
The webservice can be accessed by anyone, from any application.
The token itself is not the problem, but having the token in the GET as part of the querystring will make it readable for everybody in between the client and the server. Even if you use https. It's safer to add the token in the header of the http request (e.g. using the Authorization header); the head will also be encrypted using https (unlike the request). If you don't plan to use https, then it does not really matter, I guess.
Furthermore, I would add a filter class (and add is as property of the controller), so that you don't need to do the check in each method. But for a simple controller with 3 actions it may be overkill.

Basic authentication on a remote server

I need some help with ASMX web-services.
Let's suppose I have a ServerService which provides some data. Let's suppose it has a method GetRandomInteger which returns a random integer (obviously). It implements a custom basic authentication using IHttpModule.
public class BasicAuthHttpModule : IHttpModule
{
private UserRepository _userRepository;
public void Dispose()
{
}
public void Init(HttpApplication application)
{
_userRepository = new UserRepository();
application.AuthenticateRequest += OnAuthenticateRequest;
application.EndRequest += OnEndRequest;
}
public void OnAuthenticateRequest(object source, EventArgs e)
{
var app = (HttpApplication)source;
string authHeader = app.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(authHeader))
{
// Here I successfully get credentials from header
if (_userRepository.ValidateUser(username, password)) return;
// Return 401 and CompleteRequest
}
else
{
// Return 401 and End
}
}
public void OnEndRequest(object source, EventArgs eventArgs)
{
if (HttpContext.Current.Response.StatusCode == 401)
{
// Return 401 and require new authorization
}
}
Fortunately, it works. Now I can successfully open Service.asmx file, get basic authentication window and get access to it's GetRandomInteger method after successful authentication.
Now I have an ASP.NET MVC 4 application called ClientService. It must provide user interface with convenient and appropriate access to methods of ServerService. Now it has default controllers like Account and Home, default views etc.
I need this ClientService to authenticate on a ServerService. I mean there will be a Home/Index page with button "Login". I enter login and password there and ClientService tries to authenticate at ServerService. It returns error on fail or authenticates on success providing access to some Home/RandomInt page which will show the integer requested from ServerService. What is the best and the easiest way to do this?
How to implement registration on a ServerService? There is no AllowAnonymous attribute or something at ASMX, so I can't register user because he doesn't have access to any of methods due to 401 error.
Thank you in advance.
P.S. No. I can't use WCF or something else. I need to implement an ASMX web-service.
Update 1: OK, I have learned something new from here
http://www.aspsnippets.com/Articles/How-to-add-reference-of-Web-Service-ASMX-in-ASPNet-using-Visual-Studio.aspx
There is an old-style thing like "Web reference" and it's not an "Service reference". I have added this Web reference to my project and now I can call some methods from this ASMX page in this way:
try
{
ServerService svc = new ServerService();
svc.Credentials = new NetworkCredential("user", "password");
int a = svc.GetRandomInteger();
} catch (WebException e) {
// Auth failed
}
However, I don't understand how to link it with ASP.NET MVC ClientService authentication. So, both questions are still open. Hopefully, I will understand it or you will help me.
Here is a documentation for adding a Web reference to an ASMX Service.
http://www.aspsnippets.com/Articles/How-to-add-reference-of-Web-Service-ASMX-in-ASPNet-using-Visual-Studio.aspx
Using this information I can easily make requests to a web service.
The only thing I left to do on the moment of question update is to create a custom authentication.
When user logins, the client sends a request to a service. In case of successful basic authentication, it creates proper FormsAuthentication cookie ticket for a user. User logs in.
On each request to a service, the client extracts login from FormsAuthentication cookie and his password from server cache and uses them to authenticate on a service. In case of basic auth failure (it can only occur if user's password has been changed on the service side) the cookie is cleared and session is aborted.
Registration is implemented using another one ASMX service which is not using basic auth but is anonymous (because registration is supposed to be anonymous method).
That's it. Finally, I have found a proper solution :)

Session usage in WCF service

In my wcf project, I want to store some user information(userid or something) as we use asp.net session.After logging in, the userid will store in session
and we can retrieve it for other service.I found we can use httpcontext.current.session in wcf but that one is only support for wcf hosted in IIS.
My wcf service will be hosted in window service.Is there any way to do? Is there any variable or function in wcf to get that features?
Please guide me the right way.Thanks for your help.
//For example
//LogOnWCFService
public Boolean LogOn(string userID, string PWD)
{
currentUserID = userID;
HttpContext.Current.Session.Add("UserID",userID);
return true;
}
//ProcessWCFService
public void Process()
{
string userid = HttpContext.Current.Session["UserID"].ToString();
if(userid == 1)
{
//Do Something
}
}
I would avoid the use of sessions with WCF, espescially if you want to use the session data over different Service calls.
A better approach would be to implement your own session management. The LogOnService could create an unique sesion ID after a successfull logon and return it to the client. The session ID could be persisted together with additional informations (UserID etc.). All other services then include this session ID in every method call to identitfy itself.
nSess = logscv.LogOn(UserID)....procsvc.Process(nSess)

Categories