Azure Function App documentation using API Management - azure

I have created a Azure Function App. The function app connects to a SQL DB and has the following features
Return all the records in a table
Returns the records based on the column name using the below code
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
string loan_id = req.Query["loanid"];
string loan_amount = req.Query["loanamount"];
if (string.IsNullOrEmpty(loan_id)) {
//Do something when dont give loan id.
} else if (string.IsNullOrEmpty(loan_amount)) {
//DO something when dont give loan amount.
}
return new OkObjectResult("This is a test.");
}
I would like to document the function app using API Management/Swagger. Can you please let me know how this can be achieved?
Thanks in advance

You just need to create an API management service instance from the portal and add the function endpoint using the open api.
You can follow this documentation on how to do the same.

Related

Azure Functions with SignalR: Unauthorized when trying to get access to SignalR Service

i am currently developing a real time analytic Dashboard with Stream Analytics -> Azure Functions -> SignalRService -> Angular Web App.
I am struggling when i want to authorize my function with the signalr service. Therefore i added the Connectionstring to my Appsettings. When i try to send a SignalRMessage, it says that i am unauthroized. Isnt it just setting the Connectionstring with the Accesskey in AppSettings of the Function?
Current Error:
Microsoft.Azure.SignalR.Common.AzureSignalRUnauthorizedException: 'Authorization failed. If you were using AccessKey, please check connection string and see if the AccessKey is correct. If you were using Azure Active Directory, please note that the role assignments will take up to 30 minutes to take effect if it was added recently. Request Uri: https://signalrtest2.service.signalr.net/api/v1/hubs/pa'
FunctionCode:
[FunctionName("CreateRealTimeAnalytics")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[SignalR(HubName = "pa")] IAsyncCollector<SignalRMessage> signalRMessages)
{
// Extract the body from the request
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
if (string.IsNullOrEmpty(requestBody)) { return new StatusCodeResult(204); } // 204, ASA connectivity check
var data = JsonConvert.DeserializeObject<StreamUsageHeartbeatAnalytics>(requestBody);
var dataString = Newtonsoft.Json.JsonConvert.SerializeObject(data);
await signalRMessages.AddAsync(
new SignalRMessage
{
Target = "pa",
Arguments = new[] { dataString }
});
return new OkResult(); // 200
}
[FunctionName("Negotiate")]
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
[SignalRConnectionInfo(HubName = "pa")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
To achieve the above requirement we have tried to add the below connection string format which is working fine So please make sure that you have provided proper Connection string with below format in your Appsettings.
Azure__SignalR__ConnectionString : Value(My connection string)
For more information please refer the below Links:-
MICROSOFT DOCUMENTATION - Azure Function SignalIR Bindings
SO THREAD:- Unable to read Azure SignalR Connection String from Azure App Service Configuration Application Settings

Get function key (name) used when calling Azure Function

I need to be able to identify the key (ideally key name) provided in the header (x-functions-key) for the POST to the Azure Function in the Run method, e.g.
Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log, ClaimsPrincipal principal)
It is great to be able to protect access to the Azure Function adding Function Keys in the Azure Portal panel, but I must be able to tell which function key was used. Ideally it would be possible to associate claims on each function key, but as long as I can at least figure out which key was used I will be happy.
Simply get the claim "http://schemas.microsoft.com/2017/07/functions/claims/keyid" from the req.HttpContext.User.Claims object. It contains the key id in case a Function key was used.
Works like a charm, and does not require external lookups.
const string KEY_CLAIM = "http://schemas.microsoft.com/2017/07/functions/claims/keyid";
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
var claim = req.HttpContext.User.Claims.FirstOrDefault(c => c.Type == KEY_CLAIM);
if (claim == null)
{
log.LogError("Something went SUPER wrong");
throw new UnauthorizedAccessException();
}
else
{
log.LogInformation( "Processing call from {callSource}", claim.Value);
}
Sajeetharan answered how you can get the Keys using REST API.
About the ability to use RBAC, you need to use Managed Identities and you can find more information about how to set it up: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet
In Azure Functions v1:
[FunctionName("MyAuthenticatedFunction")]
public static async Task<HttpResponseMessage> MyAuthenticatedFunction([HttpTrigger(AuthorizationLevel.Function)] System.Net.Http.HttpRequestMessage reqMsg, ILogger log)
{
if (reqMsg.Properties.TryGetValue("MS_AzureFunctionsKeyId", out object val))
log.LogInformation($"MS_AzureFunctionsKeyId: {val}");
}
Code reference: WebJobs.Script.WebHost/Filters/AuthorizationLevelAttribute.cs#L77

Redirect service (302) in Azure, best possible approach?

I need to create a redirector that redirects user to an external domain while retaining the query params and one additional param.
e.g. When a user visits
https://contoso.com/redirect?docId=123, it will redirect the user to
https://contoso-v2.com/home?docId=123&token=xxxxxxx
Once user visits https://contoso.com/redirect?docId=123, this endpoint will process the info (from query params) and generate a token that needs to be appended in target URL.
What would be the most efficient and best way in Azure? Writing a simple Azure Web App or is there any better way?
You could use Azure Function with HttpTrigger Binding. With consumption plan the cost would be minimal (1 million invocations are free in pay-as-you-go plan).
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
var uri = req.RequestUri;
var updatedUri = ReplaceHostInUri(uri, "contoso-v2.com");
//return req.CreateResponse(HttpStatusCode.OK, "Original: " + uri + " Updated: " + updatedUri);
return req.CreateResponse(HttpStatusCode.Found, updatedUri);
}
private static string ReplaceHostInUri(Uri uri, string newHostName) {
var builder = new UriBuilder(uri);
builder.Host = newHostName;
//Do more trasformations e.g. modify path, add more query string vars
return builder.Uri.ToString();
}

Hooks for inspecting claims Azure functions?

Lets say I have two Azure functions:
public static class MyFunctions
[FunctionName("DoIt")]
public static async Task<HttpResponseMessage> DoIt(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
TraceWriter log)
{}
[FunctionName("DoSOmethingElse")]
public static async Task<HttpResponseMessage> DoOther(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
TraceWriter log)
{}
}
And then I configure the Function AppService to require AzureAD authentication. Lets say I wanted particular permissions like Role membership or other claims. I could do the following in a function I call at the top of each method:
inspect the req parameter for the bearer token, parse the JWT
look at the claims
Use AuthenticationContext or another JWT library to get Microsoft Graph tokens to get additional data
My question is are there options to do any of the following?
Create "before hook" function so every http function I write in that class or deploy to the service container goes through this inspection
Performa any of these authorization via attributes?
Access a claimsIdentity directly?
I've found some code sample related to what you are looking for:
stuartleeks/AzureFunctionsEasyAuth (Github)
So the interesting part is here (will give you the main idea):
[FunctionName("GetClaims")]
public static HttpResponseMessage GetClaims(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
HttpRequestMessage request,
TraceWriter log)
{
if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
{
var claimsPrincipal = (ClaimsPrincipal)Thread.CurrentPrincipal;
var claims = claimsPrincipal.Claims.ToDictionary(c => c.Type, c => c.Value);
// Could use the claims here. For this sample, just return it!
return request.CreateResponse(HttpStatusCode.OK, claims, "application/json");
}
else
{
return request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Not Authorized");
}
}
The simplistic solution would be to create a function that get the claims and you can call this function in every others functions.
Azure functions has Function Filters (As per the documentation it is still in preview.)
Function Filters provide a way to customize the WebJobs execution pipeline with your own logic. Filters are very similar in to ASP.NET Filters. They can be implemented as declarative attributes that can be applied to your job functions/classes.
Filters allow you to encapsulate common logic to be shared across many different functions. They also allow you to centralize logic for cross cutting concerns (e.g. validation, logging, error handling, etc.).
So you should be able to create a custom authorization filter with these information.

Error creating HttpTrigger Azure Function with CosmosDB document output

I want to make an Azure Function that takes a JSON body passed to it and inserts this document in to an Azure COSMOSDB instance.
To do so, I created this function in the Azure Functions Portal:
And implement the function like so:
#r "Newtonsoft.Json"
using Newtonsoft.Json.Linq;
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, object outputDocument)
{
var requestContent = await req.Content.ReadAsStringAsync();
log.Verbose($#"Received request:\n{requestContent}");
var newDoc = JObject.Parse(requestContent);
newDoc["Id"] = Guid.NewGuid().ToString();
newDoc["shardKey"] = newDoc.Value<string>(#"Id").Substring(8);
outputDocument = newDoc;
return req.CreateResponse(System.Net.HttpStatusCode.Created);
}
In the portal, I put in an easy sample doc:
{
"prop1": 2,
"prop2": "2017-02-20",
}
and click 'Run'
I'm immediately met with
as an overlay in the portal IDE along with
{
"id": "145ee924-f824-4064-8364-f96dc12ab138",
"requestId": "5a27c287-2c91-40f5-be52-6a79c7c86bc2",
"statusCode": 500,
"errorCode": 0,
"message": "'UploadDocumentToCosmos' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?"
}
in the log area.
There seems to be nothing I can do to fix the issue, yet I sure feel like I'm doing everything right.
What do I need to do to simply take a JSON object as an HTTP Request to an Azure Function, and insert/upsert said object in to an Azure Cosmos DB instance??
For async functions you should use IAsyncCollector:
public static async Task<HttpResponseMessage> Run(
HttpRequestMessage req, TraceWriter log,
IAsyncCollector<object> outputDocuments)
{
...
await outputDocuments.AddAsync(newDoc);
}
Can you try adding out to dynamic outputDocument?
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, out dynamic outputDocument)

Resources