Week 1, Day 5 of #30DaysOfSWA!!
So far, we've learnt to build/deploy a basic web app, add a serverless API endpoint and customize the configuration settings for both application behaviors and build workflows. But we forgot one thing - the user! To create differentiated experiences for users, we need ways to identify them and understand their role in the application context. We can then use that information to manage user access to application features (role-based authorization) as well as application access to user information (once authenticated).
Thankfully, Azure Static Web Apps makes this fairly painless. Let's see how.
What We'll Cover
- How do we secure a SWA?
- Managed authentication
- Custom authentication
- Managing user roles
- Role-based authorization
- Accessing user information
What does it mean to secure a Static Web App? It's three things:
- Knowing User Identity - Having a way to determine the identity of the user using an authentication service or provider.
- Knowing User Roles - Understanding what persona the user is taking on when (using the application), and customizing the experience accordingly.
- Managing User Access - Making sure the authenticaton information is seamlessly accessible to all SWA components, allowing them to enforce rules that allow only authorized users or roles to access resources.
Let's dive into the three concepts that tackle these needs: Authentication, Role Assignment and Role-Based Authorization.
Azure Static Web Apps comes with a default streamlined authentication experience that supports:
- pre-configured providers: Twitter, GitHub, Azure Active Directory
- pre-assigned roles: anonymous (guest) or authenticated (on login)
- customizable rules: defined for routes, in
- Want to block a specific pre-configured provider? Just add a blocking rule to their login route to ensure no user is allowed access to it.
- Want to send users to custom pages after successful or failed login attempts? Use query parameters and route rules to make this work.
This is the default managed authentication experience.
But what if you want more flexibility with the registration process (used by a pre-configured provider) or want to add a new one (custom provider)? This is where custom authentication options come in, allowing you to override the defaults.
You can configure one or more custom providers for this purpose. Azure Static Web Apps has built-in support for custom authentication using: Apple, Facebook, Google, Twitter, GitHub - and AAD! You can also configure custom providers that support OpenID Connect standard.
By configuring at least one custom provider, you are effectively disabling pre-configured provider options. To configure custom providers, add config information to the
auth section of the
staticwebapps.config.json file. This is also a good place to use Application Settings (environment variables) to store potentially sensitive configuration data in a privacy-preserving way.
Azure Static Web Apps makes custom registrations easy by providing standard route patterns for Login, Logout and User Profile requests, as well as redirect URLs for authentication callbacks (from the custom provider) on login/logout.
There are three key concepts you need to know in this context:
- Every Static Web Apps user has one or more roles assigned to them.
- There are 2 built-in roles ("anonymous" and "authenticated")
- Define custom roles & assign users by invitation or by-function.
Let's review these quickly.
- All users accessing a Static Web App are in an anonymous role (guest) until authenticated by a pre-configured or custom provider.
- Once authenticated, they have an authenticated role but can now be assigned custom roles by invitation (proactive) or by function (reactive)
- Proactive invitations can be configured and sent from the Azure Portal, using provider-specific email addresses for the user. Users now click on the invite link to login with that custom role assigned automatically.
- Reactive functions defer assignment to post-login, using an Azure Function that dynamically returns an assigned role (or roles) to the user on being given the authenticated user details.
The latter approach offers more flexibility, allowing you to use the function handler to invoke another service (like Microsoft Graph) to make the role-assignment decision for you. Read Role Management for more details - including steps to update role assignments or remove users from a role.
Once the user has been assigned a role, managing user access based on that assignment becomes easy using the built-in support for routing rules based on the allowedRoles property attached to each
route. For example, the following configuration setting (in
staticwebapps.config.json) would restrict access to all routes that start with
/profile* to only authenticated users.
Read more about securing routes with rules to understand various usage scenarios and configuration settings to enforce them.
Access User Info
One of the benefits of Azure Static Web Apps' seamless integration of application and API capabilities is that authenticated user information can be accessed transparently in two ways:
- Using a direct access endpoint at
/.auth/methat is automatically provisioned with the user's information when authenticated.
- Using API functions with a
fetchcall to the
xxxis a named function you implement to return user information.
How-Tos: Watch It!
Prefer a Video Walkthrough to understand the process? We have you covered with the Azure Tips And Tricks: Static Web Apps series. Check out the following videos:
Exercise: Try it!
One popular feature that modern web apps often support is the ability to assign a custom role to an authenticated user (based on some identifiable context) and then regulate their access to various routes or features in the application based on that assigned role. How can we make that happen in Static Web Apps?
There's a tutorial that teaches you how!
- Authenticate the user using the managed Azure Active Directory API endpoint.
- Query Microsoft Graph to determine their Active Directory group membership.
- Use that membership to assign them a custom role.
Update the application behavior in the
staticwebapp.config.json file to restrict user access to specific routes by specifying
allowedRoles for those routes. Test what happens when the custom role above is added, and then removed, from the collection of allowedRoles.