I've configured my UWP app to authenticate using a MobileServiceClient. This appears to be working fine. The ClaimsPrincipal object is authenticated when executing remotely. However, I'm unable to retrieve the ClaimsPrincipal from my Azure Function when debugging locally.
I believe this is because I need to configure my local server with a matching SigningKey, ValidAudiences, and ValidIssuers settings; as described in this article covering Mobile App Services.
But I'm working with Azure Functions and not a Mobile App Service, and configuration appears to work differently.
How can I configure my local server to correctly interpret the credentials passed from my mobile app?
I believe the reason it works remotely and not locally is because the Azure Functions local tooling does not currently support the Authentication / Authorization identity features. Until it does you'll need to find a way to mock the ClaimsPrincipal for local development/testing.
UPDATE: Same answer for Sept. 2020. We've done some work to get closer to this goal, but still not quite there yet.
Related
This question refers to the article:
https://learn.microsoft.com/en-us/azure/app-service/app-service-managed-service-identity
I'm trying to figure out how I can simulate using the service principal that is generate for my azure application to work locally.
I followed the article and when I deploy azure function to azure and run it from there, I'm able to successfully use the MSI_ENDPOINT and the MSI_SECRET to successfully get the token. However, when i run the same deployment locally it fails. I use the exact same MSI_SECRET and change the MSI_ENDPOINT to the Domain that I use to the azure function endpoint.
Example: On azure the MSI_ENDPOINT = http://127.0.0.1:41831 and locally it is http://localhost:7071 (http://0.0.0.0:7071
However, when I run it locally I get a 404 error with the request. The request is http://0.0.0.0:7071/MSI/token?resource=https://vault.azure.net&api-version=2017-09-01 with the secret in the header. Exact same params with the working one loaded on azure except for the MSI_ENDPOINT.
Any advice on how to address this so I can run and test locally?
Using the Microsoft.Azure.Services.AppAuthentication library for .NET
for .NET applications and functions, the simplest way to work with a
managed identity is through the
Microsoft.Azure.Services.AppAuthentication package. This library will
also allow you to test your code locally on your development machine,
using your user account from Visual Studio, the Azure CLI, or Active
Directory Integrated Authentication. For more on local development
options with this library, see the
Microsoft.Azure.Services.AppAuthentication reference. This section
shows you how to get started with the library in your code.
Add references to the Microsoft.Azure.Services.AppAuthentication and Microsoft.Azure.KeyVault NuGet packages to your application.
However, this library is only available in .net which i'm not using and does not really explain how you would do it via REST call.
Thanks!
As far as I understand, MSI via REST works for you in the cloud, but not locally.
Unfortunately, it seems this is currently not easily possible when you can't use the AppAuthentication library. See this GitHub suggestion.
So if you don't want to hack some debug code into your production code, you probably need to host a "custom MSI proxy" locally which just performs the classic authentication via client credentials (appId + secret) to return the token.
curl -d "grant_type=client_credentials&client_id=<removed_for_security>&client_secret=<removed_for_security>&resource=https%3A%2F%2Fvault.azure.net" https://login.microsoftonline.com/<removed_for_security>/oauth2/token
Note that I added the KeyVault as the resource parameter. See your built MSI URL - http://0.0.0.0:7071/MSI/token?resource=https://vault.azure.net&api-version=2017-09-01
In a AzureAD authenticated app hosted in Azure i get the access token in the api controller like this
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
_client.DefaultRequestHeaders.Accept.Clear();
var tokenHeader = Request.Headers["X-MS-TOKEN-ADD-ACCESS-TOKEN"];
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenHeader );
}
Since Azure AD app service injects the token it works only when hosted in Azure.
How can i make it work in my development environment? This of course generates an exception.
Im following this tutorial:
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-auth-aad#enable-authentication-and-authorization-for-back-end-app
Both backend and frontend are secured with AzureAD authentication.
The frontend app has had permission set to the backend app in AzureAD section in the portal.
In the code, there is nothing configured in appsettings.json.
According to your describe, you're using Easy Auth for your web App service. You know, Easy auth is for Azure Web App service, it's managed by Azure. So, I'm afraid of that you cannot use Easy Auth authentication for your app from your local machine.
For more detials about Easy Auth for Azure Web App service, you can refer to this documentation.
If you run the application locally on your development system, Easy
Auth will not be available and you will not have the access tokens,
etc. that you may need in your application. In order to debug those
features of your application, you will need to deploy to an Azure Web
App. An alternative approach is to do the login and authentication
workflow in the application code, but then you are no longer
leveraging Easy Auth.
However, there is a method to do Local Debugging of .NET Core Web App with Easy Auth.Here is a blog which introducts an approach to that. This blog may be helpful to give a thought for your scenario.
I have two applications:
MVC Site (User-facing Web App secured via OAuth -> Google)
Web API Site ("Private" Web Services)
These are hosted in an App Service Plan in Azure. These web services will only be consumed by my own applications - I don't need to worry about outside consumption. In fact, I specifically don't want outside consumption. My Web App is using OAuth to Google - that shouldn't matter here.
So to get to the heart of my question: My web services currently have no authentication/authorization model in the code but I don't want it just publicly available to anybody. On prem, we just lock this down via IIS using Windows Auth and set the service account for the consuming web app to run as a user that Windows Auth allows access to. I'd like to do the equivalent in Azure.
I understand Azure isn't exactly the same but I have to believe this is possible. I have even gotten my web services locked down the way I want using the settings in the Authentication/Authorization tab (I can try to navigate to it but I only get my Swagger UI once I login with a valid organizational account). So half of my battle is solved but I cannot figure out how to do the other half - the equivalent of setting the service account for my consuming MVC application to run as.
Can I do this via the portal without having to code specifically to this scenario? I'd really like a PaaS-level or IaaS-level solution for the security portion of consuming the above locked-down services. I'm also open to other avenues if I'm going down the wrong path in having a PaaS or IaaS security solution to this problem. I'm not against making code changes - we did have a one-liner in our RestSharp code to engage Windows Authentication, but the bulk of the work/configuration was outside of code and that's what I'm going for here.
If going the IaaS path you can host the application inside of an VM in the exact same way as you did before when running it directly on-top of IIS. The benefit is that you can get running the same way as before but you will still need to manage the VM; i.e install updates and take care of its security.
However, if you want to have a PaaS solution, then you need to modify the code of your front-end application to pass on the authentication token to the back-end API, assuming the back-end accepts the same authentication as the front-end. See https://azure.microsoft.com/en-us/documentation/articles/app-service-api-dotnet-get-started/ as an example on how to pass on authentication information from one app to another.
Alternatively you can use the app identity to make calls to your back-end API. This way the calls are not related to any user but are instead done in the context of the app. See https://github.com/Azure-Samples/active-directory-dotnet-daemon for more details on how to set it up, both configuration and needed code.
If you want to allow your users to sign-in using their Google accounts then you could handle authorization to your API using the app identity (second alternative above), assuming the API is independent of the requesting users identity.
Enabling authentication for a Azure Web App directly through the menus in the Azure Portal adds Azure AD authentication in-front of your application and require your to pass an access token generated by Azure AD to your API for it to work.
I am currently doing some research for the development of a mobile application for our company that should support offline data sync (on an iPad). We have explored many possibilities including PhoneGap/Cordova, Xamarin and simply native iOS development. Xamarin, for many different reasons, seems to be our best choice, so my question will assume we will develop in Xamarin.
I was looking into a library for managing offline data synchronization and the most obvious solution is Microsoft Azure MobileServices. However, my company is Canadian, and apparently it's hard to trust (legally) our data to clouds based in the US. Since we already deployed internally our WebApi on our intranet, I figured there was probably a way to point the MobileServices library to our own WebApi. I have read about the Azure Hybrid Connection possibility, but our data still conveying through Microsoft servers might not be a possibility. So, my question is this:
Is there a way to configure the Microsoft.WindowsAzure.MobileServices Client library to point directly to our intranet, RESTful WebApi backend, without going through any Microsoft Azure servers ?
I understand that, in order to be able to use the Client librairies seamlessly, we probably would have to adapt our WebApi to implement the necessary .net Backend interfaces. I'm mostly wondering if it's even possible as the MSDN documentation on the libraries all seem to point to direct connections to their servers (no possibilities to configure your own connection strings) and all instructions redirect you to their Azure Mobile Services website.
Thank you.
If you look at the API for your mobile client, you'll notice that the Azure Mobile Services Client SDK only cares about two things:
new AzureMobileClient( url, appkey)
...where it's hosted shouldn't be a concern. Everything else is just configuration.
If you want to host the Azure Mobile Services Backend on your own servers, technically you could do this, but there are likely a few caveats. Microsoft has announced that they will be launching a Canadian Azure data center, but we won't see it until 2016.
In the meantime, here's how you can host the services locally. Note that I have not tried to emulate all of the features of Azure Mobile Services (aka Zumo) so your mileage (or kilometerage) will vary.
Hosting Locally:
From a technical feasibility, you absolutely can run the services locally. I know this because you can create the Azure Mobile Services Backend project from within Visual Studio and run it locally for development purposes. This is what our development team does for testing their mobile applications.
Note that you can create the Azure Mobile Service backend directly from within Visual Studio: New Project -> Cloud -> Azure Mobile Service. You can also download the exact same template (pre-configured with your URL and ApplicationKey) directly from the Azure dashboard: Create -> Mobile Service.
Obviously, if you're hosting it on your server it will be up to you to configure and use a proper SSL certificate for your site.
ZUMO Permissions:
By default, the security roles on the server are turned off. So if you're locking down any of your methods using the [AuthorizeLevel] attribute these settings will be ignored at runtime. If you need to enable this feature you can do so by modifying the WebApiConfig.Register() method and marking the site as self-hosted: config.SetSelfHosted(true).
Configuration:
From a configuration perspective, the Azure Mobile Service dashboard provides several tabs for configuring Identity, Push Notifications, Connection Strings and App Settings. Sadly, you won't have a dashboard, but all of these settings have a corresponding value in the local web.config. Any value you provide here is automatically overwritten in Azure, but they're used when running locally.
The minimum settings you'll need to configure are listed here. The ApplicationKey you can distribute with your ZuMo client, but the MasterKey is for the Admin authorization level so you'll want to keep that secret. The MobileServiceName is used by the EntityFramework for your database schema and what appears in the URL of your site.
<add key="MS_MobileServiceName" value="myzumosite" />
<add key="MS_MasterKey" value="masterkey" />
<add key="MS_ApplicationKey" value="appkey" />
Values that start with a MS_ prefix map to corresponding values in the Azure Portal. MS_GoogleClientID and MS_GoogleClientSecret map to the Google Identity values in the dashboard, for example.
Any other value in the AppSettings node is immediately accessible via the ApiServices.Settings property and corresponds to the Settings node in the Azure dashboard.
Database connection strings continue to exist in the connectionStrings node. The same is true for azure notification hub.
Database:
Obviously, the database you configure will be up to you as well. Permissions and User accounts are also obvious. There may be some minor differences between the SQL Azure syntax for Entity Framework database migration scripts that you'll need to worry about. (I've discovered the database migration scripts don't work from the Package Manager, but they do work when the database scripts are run when your website starts)
Caveats:
You will not have a nice dashboard for monitoring performance of your site, reviewing logs or changing runtime settings
You will not be able to scale out your site immediately; Scaling and deployment will be your problem
Deployment configuration is your responsibility (Project -> Publish won't be available unless you configure it)
Not sure if you'll be able to use Azure Active Directory as an authentication scheme, though from the sounds of it that won't be a concern. You can write your own authentication providers: Microsoft's Zumo library only supports a handful, but the underlying Owin.Security package that Microsoft uses supports several dozen systems!
Your site will need to be publically visible to your mobile clients
Push Notifications should work, but you will be using Azure's notification hub for this.
I have no idea where ApiServices.Log will go
The easiest path to take would be to:
Create the Mobile Service in Azure to get the notification hub and settings preconfigured
Download the starter site from the dashboard
Configure the web.config as mentioned here.
It's not possible to simply configure WAMS Client library to work with your own WebApi Backend.
But WAMS library is available at github, so I'm sure you can reuse a lot of code from the WAMS project, especially if you want to use a PCL project.
To route your data securly through Azure, you could think about setting up express route. Additionally, for last weeks update, it's possible to apply a custom domain to the WAMS Backend, including your own certificate to secure your connection.
According to the releases a few day ago by Scottgu, its now possible to use the windows azure management api without client certificates.
Are there any examples of doing this?
I have a Azure Cloud Service Package that I would like to let people deploy from my website. Therefore I would like to, from javascript, to authenticate the user to their Azure subscription ( some oauth against the WAAD ) and then by rest api deploy my package for them.
I dont need a concrete examples, but just some pointers on how I could do this.
I dont want users to give me their passwords offcause, therefore i need some guidance on how I can do SSO of the user against WAAD/Windows Azure management api and from there use the access token to deploy the package.
As of today, the Service Management API documentation regarding this new authentication mechanism (http://msdn.microsoft.com/en-us/library/windowsazure/ee460782.aspx) is not updated. Since the new login mechanism is supported in PowerShell which is essentially a REST Wrapper over this API and is open source, one thing you could do is take a look at the source code of the Cmdlets on Github (https://github.com/WindowsAzure/azure-sdk-tools) to see how it is accomplished there and write something of your own (and share it here:)).