Calling Microsoft Azure functions from Windows Applications - c#

How to call Azure functions on azure from a Windows Application running on local machine, without embedding the keys in the Application?
Is there a Client Proxy Generator like the one for WCF Services but for Azure functions instead? or do you just use web client ?

You can use Restsharp to access an Azure Function.
You will need to get the full Url containg the host key from the portal.
Navigate to your function in the portal.
Use the </> Get function URL link for the function to get the full URL (next to the Run button at top of page). The key is after "code="
var fullUrl = "https://myfunciton1000.azurewebsites.net/api/ResourceGroupNameExists?code=ENp/dFAluLqHM8TDr...Sk5YJ7DSEbs0PHPzTVw==";
var url = "https://myfunciton1000.azurewebsites.net/api";
var securityCode = "ENp/dFAluLqHM8TDr...YJ7DSEbs0PHPzTVw==";
var client = new RestSharp.RestClient(url);
var request = new RestSharp.RestRequest("ResourceGroupNameExists", RestSharp.Method.POST);
request.AddHeader("x-functions-key", securityCode);
request.AddQueryParameter("ResourceGroupName", "ImageStormSource");
var response = client.Execute(request);

Calling an Azure function from a .NET application is simply a matter of issuing an HTTP request to the endpoint: https://social.msdn.microsoft.com/Forums/azure/en-US/2c676980-8dd3-4112-ae41-a2c4f4825fe3/how-to-call-a-azure-function-from-aspnet-webhook?forum=AzureFunctions
The communication between Azure and the client application is encrypted using SSL.
As far as the key is concerned, you could either hard-code it into your client code or configuration or retrieve it from some service of yours.

If your azure function app is using HttpTrigger it is no different than any non Azure WebAPI app. You call it via a rest client using either just basic a HttpClient or a wrapper library like RestSharp.
There is nothing special you have to deal with, go find any tutorial on how to call a WebAPI app for more information.

Related

C# Swagger generated client with domain authentication

We have a simple rest API exposed with Swagger UI. We usually copy-paste the raw definition to editor.swagger.io, and generate a C# client. The generated code works very well - but we work in a Windows AD environment, and we cannot find any way to tell the client to use the current user credentials during the communication. So the IIS hosted rest API throws Unauthorized exception - as it is set to Windows authentication mode.
Is it possible to use the generated client this way? Any option to add to the API definition to generate such a client?
Writing a client manually is easy:
var client = new WebClient();
client.UseDefaultCredentials = true;
...
but we would like to generate it ... but the Configuration contains nothing about credentials ... :(
public static IO.Swagger.Api.IBookingApi GetBookingApiWebApi()
{
var basePath = ConfigurationManager.AppSettings["web.api.url"];
var api = new BookingApi(basePath);
return api;
}
Thanks in advance...

Calling Marketing Cloud APIs from C# via FuelSDK

In am trying to get an access token to call Salesforce Marketing Api through FuelSDK the code is:
NameValueCollection parameters = new NameValueCollection();
parameters.Add("clientId", "myclientidvalugoeshere");
parameters.Add("clientSecret", "myclientsecretvaluegoeshere");
var client = new ETClient(parameters);
ETFolder folder = new ETFolder();
folder.AuthStub = client;
var response = folder.Get();
return response.Message;
But it's returning:
System.Net.WebException : The remote server returned an error: (401) Unauthorized.
I am not really sure if I am doing it the right way.
What I really want to do is to connect to Salesforce Marketing cloud through FuelSDK C#, using Oauth authentication to get access token for the user and call the resources needed.
You probably need to add authEndPoint, restEndPoint, as well as useOAuth2Authentication to your NameValueCollection parameters.
Check this out: https://github.com/salesforce-marketingcloud/FuelSDK-CSharp/wiki
There's a feature called whitelist. Try to add there Your IP and also double check that You are using the correct API Keys.
From my experience the response You are receiving is becasue the combination of API key strings are not the correct ones.
I would recommend that You try the same keys to do a simple REST API request on the same package. Find more on this here.

What is the Authorize Endpoint when the web app and the apis server are deployed seperatly?

In ASP.NEt Zero, I am trying to integrate with Zapier using Identity Server 4. I managed to run it, however, what will authorize endpoint would be?
I am using .Net core with angular version where the login is happening in another web server. However, OAuth2 needs an authorization endpoint where the user authenticate, authoirze the app, and return a token.
I've assumed you're trying to get the endpoint on the server-side. To get any endpoint for your IDP, you need to read your IDP's discovery document, located at http://youridpurl.com/.well-known/openid-configuration. You can do this with the help of IdentityModel as follows:
var client = new HttpClient();
var disco = await client.GetDiscoveryDocumentAsync("https://youridpurl.com");
var authorizeEndpoint = disco.AuthorizeEndpoint;
See the IdentityServer4 and IdentityModel documentation for a more information.

How do I setup a valid on-premise ADFS URI?

I have a .NET 4.6.2 Windows client application which needs to get an authentication token from our on-premise ADFS server and use it to call an ASP.NET Core REST API. It's client name, id (GUID) and re-direct URI have been registered with ADFS. I am using the latest ADAL (v3.13) library to facilitate the authentication. I am attempting to get a token as demonstrated in the ADAL sample code like this:
AuthenticationContext authenticationContext = new AuthenticationContext("https://<adfs-sts-server>/<rest-api-host>", false);
var result = authenticationContext.AcquireTokenAsync(<rest-api-resource-uri>, clientId, redirectUri, new PlatformParameters(PromptBehavior.Auto));
The AcquireTokenAsync call returns an error, saying: The browser based authentication dialog failed to complete. Reason: The server has not found anything matching the requested URI (Uniform Resource Identifier).
Can anyone tell me:
Is the "requested URI" refered to in the error the https://<adfs-sts-server>/<rest-api-host> or <rest-api-resource-uri>?
Do I need to register <rest-api-host> or <rest-api-resource-uri> with ADFS in some way, and if so how?
Any other information I need to get this to work?
Thanks!
Peter
Using Active Directory Federation Services (ADFS) to provide authentication for on-premise endpoints from a Windows Client
Configuring ADFS
There are 2 parts to configuring ADFS.
Register the client application with ADFS
ADFS needs to be able to identify the application requesting user authentication, whether it be a service, WPF application, Web client or Office Add-in. I have gone generic and added the following client, which we can use for most of our C# requests; we may need to register a new client with different callback for Web clients.
Use one of the many tools out there to generate a GUID for the client ID.
* CLIENT_ID and APP_NAME should be unique.
* For a web client the redirect URI is where the auth service will redirect your call after authenticating the user. It should be an endpoint where you can process the token and continue with your client application. The redirect URI is not really used with rich clients/services/add-ins.
CLIENT_ID = 26E54EC9-7988-4DAE-A527-483A8A78B1C6
APP_NAME = Investplus
DESCRIPTION = Invest+ rich client suite
REDIRECT_URI = https://server/redirect-adfs.html
Instructions for Client registration
(may be possible in a wizard, but this is what I found on the web and it worked fo us)
Log on to the AD FS server as administrator and open a Windows PowerShell command window.
Enter the following command. In Windows PowerShell
Add-AdfsClient -ClientId <CLIENT_ID> -Name <APP_NAME> -RedirectUri <REDIRECT_URI>
Register the resource to be accessed ('Relying Party' in ADFS speak)
I found this link useful, it takes you through the steps of the wizard for setting up a relying party.
Instructions for Relying Party registration
The administrator on the server team will need to use the ADFS Add Relying Party Trust Wizard, and under the "Select Data Source" step select Enter data about the relying party manually.
Values you need to supply for this wizard:
DISPLAY_NAME = "MyInvestApi" (Unique display name for this Relying party)
PROFILE = "AD FS Profile"
ENABLE_SUPPORT_FOR_WS-FEDERATION_PASSIVE_PROTOCOL = true
URL = "https://server/api" (Unique URL for this RP)
ADD_ONE_OR_MORE_IDENTIFIERS = eg. "urn:myInvestApi" and "https://server/api"
ACCEPT_REMAINING_DEFAULTS
when given the opportunity, Add Claim Rules:
SEND_LDAP_ATTRIBUTES_AS_CLAIMS = true
ATTRIBUTE_STORE = Active Directory
SELECT_USEFUL_ATTRIBUTES = User-Principal-Name; Email; Display-Name
Configuring/Coding the Client application
Microsoft provides Active Directory Authentication Libraries (ADAL) for a range of platforms and languages from C# to Javascript, and from iOS to Cordova to Node.
The API exposed has changed significantly in each major version: I am using the latest C# library, currently 3.13.5.
The library makes the coding very simple, just a few lines; where I had problems was:
I couldn't find an explanation of what URL to use for the ADFS
Secure Token Service (STS)
I couldn't find documentation of the whole process as I am doing here (most documentation focussed on Azure FS), I struggled to work out
how the values provided to ADFS for Client and Relying party mapped
to the values used in the code.
What is the ADFS endpoint/URL to use in code?
Microsoft's best practice is to name your ADFS/STS server URL https://sts.domain.com (some people use https://adfs.domain.com, ask your server admins). However, if you try to hit this from a browser you'll get a 404 - Not found and trying to retrieve a token in the code, the ADAL library reports:
The browser based authentication dialog failed to complete. Reason: The server has not found anything matching the requested URI (Uniform Resource Identifier).
This is how I found the endpoint to use:
ADFS pubishes federation metadata at 'https://sts.domain.com/federationmetadata/2007-06/federationmetadata.xml'
Extract this file and open in a text editor.
When configuring the Relying Party, we specified "Enable Support for WS-Federation Passive Protocol" when specifying our resource endpoint, so search the XML for PassiveRequestorEndpoint.
Use the <Address> from this node - in my case https://sts.domain.com/adfs/ls/. I don't know if this will always be the value, or if it is specified when ADFS is setup and therefore potentially different per site.
What other values to use in the code?
We want our client app to retrieve a JSON Web Token (JWT) from ADFS which we can pass to our protected resource for authentication/authorization purposes.
At its most simple, the access token can be retrieved in 3 lines of code + configuration, and this will show how to translate what we have configured in ADFS to the values required by ADAL:
var stsEndpoint = "https://sts.domain.com/adfs/ls/";
var relyingPartyIdentifier = "urn:myInvestApi"; // Tenant in Azure AD speak, but this is an on-premise service
var authority = stsEndpoint + relyingPartyIdentifier;
var restResourceUrl = "https://server/api";
var redirectUri = "https://server/redirect-adfs.html";
const string CLIENT_ID = "26E54EC9-7988-4DAE-A527-483A8A78B1C6";
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
var asyncRequest = authenticationContext.AcquireTokenAsync(restResourceUrl, CLIENT_ID, redirectUri, new PlatformParameters(PromptBehavior.Auto));
var accessToken = asyncRequest.Result.AccessToken;
Useful references
ASP.NET Core Token Authentication Guide
ADAL - Native App to REST service - Authentication with ACS via Browser Dialog
Create a line-of-business Azure app with AD FS authentication
OAuth 2 Simplified
To issue the token for the web API, we need to make the ADFS to aware it by creating a relying party trust for the web API. And when we add a replying party we need to specify the identifiers for the replying party like figure below(Windows Server 2012 R2):
Then we can use this identifiers as the resource URI to acquire the token for this replying party. Please ensure that the resource URI is correct as you config like figure above.
And here is an article about developing with ADFS using OAuth:
Developing Modern Applications using OAuth and Active Directory Federation Services
Depending on the version of asdf, you may be able to use 'discovery' to obtain the endpoints to use.
Have a look at this post for more details: http://www.cloudidentity.com/blog/2015/08/21/openid-connect-web-sign-on-with-adfs-in-windows-server-2016-tp3/

AuthenticationToken is null

I'm currently writing a C# metro app for the Windows 8 consumer preview which fetches some data from my REST-based web services. I want the app to authenticate against the services using the Windows Live account of the current user. Therefore, I added the Windows Live SDK to my solution and pasted the following snippet from the documentation into my login view:
LiveAuthClient liveClient = new LiveAuthClient();
LiveLoginResult loginResult = await liveClient.Login(new string[] { "wl.signin" });
After the login call has succeeded, I want to pass the encrypted AuthenticationToken of the LiveConnectSession via SSL to my webservice which should decrypt the token and read the information it is interested in (that's what the documentation suggests for such a SSO scenario). But sadly, the AuthenticationToken property of the session is always null. Am I missing something here?
I ran into the same problem and realised I had two issues with my configuration:
I didn't have a "Redirect domain" defined in the API settings of https://manage.dev.live.com
I wasn't using the overloaded LiveAuthClient constructor
For example in the API settings you specify:
Redirect domain: http://localhost/myapp
You then use the constructor overload of the LiveAuthClient:
var authClient = new LiveAuthClient("http://localhost/myapp");
var loginResult = await authClient.LoginAsync("wl-signin");
//this should no longer be null
var authToken = loginResult.Session.AuthenticationToken;
The redirect URI doesn't need to point to a working endpoint from what I can tell, as long as the two values match you should be in business.
Have you registered your app on the Live Connect app management site for Metro style apps? You need to register it here for it to work with Live Services. It will give you following instructions after you have given the app package a name and publisher.

Categories

Resources