WELCOME TO CLOUD MATTER

Search
  • Roman Guoussev-Donskoi

Angular In Azure: secure API access

Updated: Dec 15, 2019

Summary

Angular like any other single-page (SPA) application needs to access back-end API to retrieve and update data.

And Azure functions is a popular way to build APIs in Azure.


The question comes then how to secure access to your Azure functions (or Azure API management) in this scenario?


Background

One of the approaches to secure Azure functions is use HttpTrigger AuthLevel attribute.

Example is shows in code snippet below.


The default is AuthorizationLevel.Function which requires a function-specific API key to call a function.

Something like below:


The issue with this approach is that anyone accessing your site can use Developer Tools in browser and see the function code value and therefore invoke your function outside of your application (for example using Postmen or any other development/testing tool), which is probably not desirable.



Secure an HTTP endpoint in production

For production environment Microsoft recommends different form of access control which are documented in Secure an HTTP endpoint in production.


Following options are suggested

  • Turn on App Service Authentication / Authorization.

  • Use Azure API Management (APIM) to authenticate requests.

  • Deploy your function app to an Azure App Service Environment (ASE).

Implementation approaches one can leverage for the first option are described below. Will review remaining options in subsequent blog posts.


Angular Adal Module

Probably one of the easiest ways to call Azure Function protected by App Service Authentication is leveraging Angular Adal module provided by Microsoft. The documentation is very clear and configuration is very simple. Essentially it works "out-of-the-box".

One needs to install the microsoft-adal-angular6 package, import MsAdalModule, configure Adal options, and secure routes using canActivate: [AuthenticationGuard].


Example is shown in snippets below:


1. Initialize in angular-sample\src\app\app.module.ts

2. Protect routes in angular-sample\src\app\app-routing.module.ts:

References and Code samples

Complete documentation is provided at microsoft-adal-angular6 by Microsoft and is pretty good. Would probably be better if examples would not use configuration elements like Client/App ID coded inline and provided a link to the working "Hello World" sample in public git repository.

To cover those requirements and provide end-to-end scenario I've created angular-azure-function-aad example in GitHub. It is build on top of Angular Tour of Heroes App and Tutorial. Hope it will help folks who follow this path.


Drawbacks

Implicit Flow: microsoft-adal-angular6 has been created as a wrapper over Microsoft ADAL (Azure Active Directory Authentication Library). Active Directory Authentication Library (ADAL) for JavaScript as of Dec 2019 states that "Implicit flow is used by ADAL JS to get tokens."


At the same time OAuth 2.0 Security Best Current Practice does not recommend to use the authorization code grant with Proof Key for Code Exchange (PKCE) to request access tokens from SPAs, as opposed to the original OAuth2 spec proposing use of the implicit grant for that scenario.


Therefore seems microsoft-adal-angular6 is using approach which is no longer recommended.


Fortunately there are other ways we can get access to back-end API described below.


Azure App Service Authentication

One of the possible drawbacks of using Adal Module that the configuration is done in the code.

If we could leverage Azure App Service Authentication configuration we could separate code from Authentication concerns (at the expense of some flexibility). We would have enabled a single Access Control enforcement point (as opposed to having configure it for each route), and greatly help with automation of security audits.


As occurs this is in fact possible but requires more configuration than just enabling App Service Authentication on Angular and Azure Function endpoints. This is still quite simple (once you know what to do) but seems to lack documented step-by-step instructions. I am sure at some point Microsoft will provide end-to-end tutorial and instructions but for now one can use steps below:

  1. Deploy Angular app and Azure function into App Services in Azure.

  2. Create App registration in Azure AD.

  3. Configure Azure App Service Authentication for both Angular and Azure Function App Services using App Registration created in #2. (e.g. Use Azure portal or PowerShell)

  4. Configure secret Angular App Service Authentication.

  5. Update additionalLoginParams in authsettings section of Angular Website config

  6. Configure HttpInterceptor to pass access token to Azure Function

Steps 1-3 below are standard steps required for configuring Authentication for any App Service.

Steps 4. and 5. are less common so below describes the details as well as step 6 where token is actually passed when calling Azure function.


Step 4 - Configure secret Angular App Service Authentication.

To access Azure Function configured with Azure AD authentication we need to provide access token. We use .auth/me endpoint to retrieve access token.

As per Microsoft engineering team when client secret in auth settings is not provided

then EasyAuth will sign in using the implicit grant flow with a response_type of “id_token”, which provides the id token only.

Client secret is also provided, then EasyAuth will use the auth code grant flow, which give us access to an access token and a refresh token.



Step 5 - Update additionalLoginParams in authsettings

At this point access token will be provided but attempt to access Azure function using it as Bearer token still returns 401 (Unauthorized).


As described in the Configure App Service to return a usable access token we make sure the angular app get’s correct access_token.


Use Azure Resource Explorer to set additionalLoginParams in authsettings section of Angular Website config as below.


Step 6 - Configure HttpInterceptor to pass access token to Azure Function

Configure Angular HttpInterceptor to add access token to outgoing requests.

This step is already included in the provided Github sample.


After this our Angular Application configured with EasyAuth can successfully access Azure Function and pass Bearer access token (assuming the are both using the same app registration as described in steps 1-3).




References and Code samples

End-to-end scenario is covered in angular-azure-function-easyauth example in GitHub.


Acknowledgements

Huge thanks to Elena Neroslavskaya who researched and provided critical information for this implementation and to David Odhiambo for supporting all the way until we found the solution.



2,165 views0 comments

Recent Posts

See All

Databricks is an amazing platform for data engineering, data science and machine learning. One of the critical requirements of secure data processing is data audit - the ability to identity what data

SAS access to storage account is very convenient and easy and while Microsoft recommends that you use Azure AD credentials when possible as security best practice still SAS sometimes hard to avoid. Le

 

Subscribe

 

CONTACT

Your details were sent successfully!

Computers