How do I extract an ip address in the azure api management policy? - policy

Is there an out of the box policy to extract the incoming ip address? I could not find one.
Do I need to write code to do that? If so, how do I go about it? What are the other alternatives?

You can extract IP address in any policies using policy expressions. The expression would be context.Request.IpAddress

You can definitely use policy expressions.
But an easier approach might be the below:
If your goal is to capture the origin IP address (and not Azure's) on your backend (for logging purposes, etc.), then:
Whenever Azure API Management Studio forwards requests to your backend, it includes the header X-Forwarded-For
E.g.
{[X-Forwarded-For, 123.45.67.891, 13.75.131.25:1795]}
The first IP Address is the one you want.
The second IP Address is actually Azure's.
E.g. First, A mobile app makes a request to Azure API Mgmt --> Second, Azure API Mgmt forwards the request to your back end --> Lastly, you capture client's the IP (i.e. the mobile device's IP) from X-Forwarded-For.
How you capture the IP from the headers on your backend is up to you and what technology you're using (e.g. ASP.net core, node.js, etc.).
Here's a snippet of code where I'm capturing the IP
private LogMetadata BuildRequestMetadata(HttpRequestMessage request, Task<string> requestBody)
{
var headers = request.Headers.ToDictionary(d => d.Key, d => d.Value.Join(", "));
// If header X-Forwarded-For is included,
// it means the request is coming from Azure API MGMT studio.
// Example header value: {[X-Forwarded-For, 123.45.67.891 (Mobile Device), 13.75.131.25:1795 (Azure API Mgmt)]}
var clientIp =
headers.ContainsKey("X-Forwarded-For")
? headers["X-Forwarded-For"].Split(',')[0]
: request.GetOwinContext().Request.RemoteIpAddress;
}

Related

How to make API request with bearer token from anyone around the world?

I am a newbie in integrating APIs and so I am encountering some issues that need help.I have been working with Clash of Clans API for some weeks. I want to make a website where users can make request and get data from the server. **To use the API, a JSON Web Token is required and it needs to be passed as part of every request. The token is bound to rate limitations and specified IP addresses. **
What I have been doing is, create a token with my IP address, get the token and make request using it. Now, I want to take this a step forward but I have no idea how to take request from users around the world.
I thought of taking keyword from the user and making request from the server but don't know the step forward. Or maybe I should make requests using my server's address from my PC? Which I don't know how. I will appreciate it if someone could explain to me with this in layman's language and if possible through a reference. Thank you in advance.
There are many ways to design for Clash of Clans API architecture.
I just to make a simple design base on quick review of Clash of Clans limitation.
API_KEY can add IP address only when create API_KEY.
It means can't update (add) user IP address after create API_KEY.
Step 0 : Create API_KEY
Clash of Clans server only allow specified IPs and API_KEY for REST API call.
You need to know your server IP v4 address(production purpose) and your IP address(debugging purpose)
your IP address get from google search
After create key, you (developer), develop(or debugging) your API.
This is created API KEY in CC server
This example, using Postman check API.
Step 1 : User login
With his User ID and password. it will save into your server with hashed value.
(It means not save password, save hashed data). it can verify but if leak to hacker much more safe.
Use request API call(or service) to your server
Step 2 : Your server forward API to CC server
Server verify user is valid
If valid user, server forward API call into Clash of Clans(CC) server by CC API with API_KEY(Bearer Token)
Step 3 : CC server check correct API call
CC server verify by compare called API_KEY/IP address with saved API_KEY/IP address
Step 4 : CC server return API response to your server
Your server received the server API call
Step 5 : Your server return to user
User received her request a service
This API list
You can test it from your home.
This is example API call via CC server's documentation

Is it possible to use Azure Blob Storage on a website that has no authentication?

I need to create a way for anyone who visits my website to upload an image to an Azure Blob Container. The website will have input validations on the file.
I've considered using an Azure Function to write the validated file to the Blob Container, but I can't seem to find a way to do this without exposing the Function URL to the world (similar to this question.
I would use a System-Assigned Managed Identity (SAMI) to authenticate the Function to the Storage account, but because of this, anyone could take the Function URL and bypass the validations and upload.
How is this done in the real world?
If I understand correctly, the user uploads a file via an HTTP POST call to your server, which validates it. You would like to use an Azure Function to then upload the validated file to the Blob Storage.
In this case, you can restrict the access to the Azure Function; so that it can only be called from your server's IP. This way the users cannot reach that Function. This can be done via the networking settings, and is available on all Azure Function plans.
You could also consider implementing the validation logic within the Azure Function.
Finally (perhaps I should have started with this), if you are only considering writing an Azure Function to upload data to a Storage Account, you should perhaps first consider using the Blob Service REST API, specifically the PUT Blob endpoint. There are also official Storage Account SDKs for different languages/ecosystems that you could use to do this.
• Since, you are using an Azure function default generic URL on your website for uploading blobs with no authentication, I would suggest you to please create an ‘A’ host record for your function app. Considering that you have a website, you may be having a custom domain for your website to be unique and as you might be having a custom domain, the custom domain’s DNS records must be hosted on a public DNS server. Thus, similarly, on the same public DNS server, you will have to create an ‘A’ host record for the function app and assign it the same public IP address that is shown and assigned in Azure. This will ensure that your public DNS server has an active DNS resolver for the function app globally and then ensure to create a ‘CNAME’ record for your default generic Azure function app URL with the same URL as the alias in the DNS records and the ‘A’ host record as the assigned value in it.
In this way, whenever, any anonymous person visits your website and tries to upload an image, he will be shown the function app URL as ‘abc.xyz.com’ and not the generic Azure function app URL thus successfully ensuring that your objective is achieved.
• Once the above said has been done, then publish the new ‘CNAME’ record created in the public DNS server as your function app URL. This will not expose the generic Azure function app URL and mask it as well as ensure that it is secured since you will be uploading an SSL/TLS certificate for the website to be HTTPS protected in the function app workspace itself as shown below in the snapshot: -
For more information, kindly refer the below documentation link: -
https://learn.microsoft.com/en-us/azure/dns/dns-custom-domain

How can I limit API access to a limited set of domains

I'd like to limits API access from one or more domains - in other words I have a set of exposed API endpoints but I only want to respond to specific remote servers.
I intend to issue tokens to the servers that I intend to respond to but I want to ensure that I'm really dealing with the right servers in case the tokens become public knowledge.
I thought I would be able to use Origin or Referrer from the HTTP headers but perhaps because I'm sitting behind an Nginx front end, those headers don't always seem to be visible.
Any suggestions gratefully received.
You can't find domain names by ip (nslookup/dig $IP) becausethe reverse resolution requires an entry in the reverse zone (dns) configured for that ip. Not everyone sets up a reverse zone and, more importantly, many domain have just an A record configured.
Using other informations coming from the request itself, IMHO, are not a valid solution because these information can be forged so there's an high chance they make be "fake".
The best solutions I can suggest you are:
Filter by ip: if you know who's going to call your api, they know what's the ip they're using to call your webserver. Configure apache so allow access to such ips.
Configure a client side authentication on your api so only those with a valid and authorized certificate (which doesn't need to be signed by a valid CA: you can create and use your custom CA) will be able to connect.
Limiting CORS / origin headers is one way if your API calls are coming from client side.
If its from server side call, IP is one way, but not guaranteed if there are many network hops in between and references are not passed by load balancers.
May be you can try something like this (Node.js):
const whitelist = ['https://www.example.com','https://www.example.com'];
const corsOptions = {
origin: (origin, callback) => {
if(whitelist.indexOf(origin) !== -1){
callback(null, true)
}else{
callback(new Error('Not allowed by CORS'))
}
},
optionsSuccessStatus: 200
}
replace https://www.example.com with your domains.

Get Client Machine Name and ID - ASP.NET Core 3.1

I need to get the computer name and id of a client when it uses my SSO web .net core application.
My first solution was to this for the machine name:
var machName = Environment.MachineName;
And this for the machine id:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
// consider ethernet interfaces
if(nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet && nic.OperationalStatus == OperationalStatus.Up)
{
return Ok(nic.GetPhysicalAddress().ToString());
}
}
Then is dawned on me that these are getting the name and id from the server, as in my computer.
I am currently debugging the request info including the header info, but I can't see anything in the header that correlates to the name and id. I am able to get the request IP and user agent from the HttpContext which is something i need, but not the name and id.
As far as I know, it's impossible actually to get client machine name and host name is not client machine name.
The client will send request to the server, so we could only get the parameter through request.
The request contains below things:
Request IP address (TCP/IP)
HTTP headers
That's all. IP address is an IP which is given by your Internet provider, and host name is name of some provider machine which Internet traffic passes through.
From request IP you cannot get real client machine name in general. In HTTP headers browsers also don't pass machine name.

azure api management error 500

I configured an Api using API management service in Azure, all the endpoints are working fine, I defined some rules into the inbound policies, the last one is a set backend service rule. the objective of this rule is redirect the request to a diferent endpoint based on certain conditions. The problem is as follow: If i test the api endpoint inside the Azure,using the the Test option provided by API managemen service all the proceess works fine, i can see into the trace and check how the Api Management service recieve the request, check the conditions definen into the inbound policy and finally change the backend url to the right endpoint. If test outside the Azure, for example using postman, the API management service response an 500 error, the description of the error is: Expression value is invalid. Value is not a valid absolute URL. () Section : (inbound) Source : (set-backend-service)
I found the issue and the solution. The problem was generated in the policies configuration. For some reason the base tag in the backend policy was deleted. Putting back the base tag all the endpoints works fine.