Azure / Azure/static-web-apps

Azure AD Claims with Static Web Apps and Azure Functions (Authorization)

Open
#988 20 comments 5 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
346
Forks
67
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**

Azure AD app role claims are not supplied to Azure Functions when linked with Azure Static Web Apps using the "bring your own functions" / linked backend approach. This impairs implementing authorization against endpoints.

**To Reproduce**
Steps to reproduce the behavior:
1. Create an Azure AD application with some custom app roles; eg:

image

2. Create a Static Web App and a Function App
3. Both the SWA and FA should use the Azure AD application and be [*linked*](https://blog.johnnyreilly.com/2022/10/14/bicep-static-web-apps-linked-backends)
4. Take a look at the `/.auth/me` endpoint in the SWA - note the claims; they should include one of your custom app roles. eg `OurApp.Read`

```json
{
"clientPrincipal": {
"identityProvider": "aad",
"userId": "d9178465-3847-4d98-9d23-b8b9e403b323",
"userDetails": "johnny_reilly@hotmail.com",
"userRoles": ["authenticated", "anonymous"],
"claims": [
// ...
{
"typ": "http://schemas.microsoft.com/identity/claims/objectidentifier",
"val": "d9178465-3847-4d98-9d23-b8b9e403b323"
},
{
"typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
"val": "johnny_reilly@hotmail.com"
},
{
"typ": "name",
"val": "John Reilly"
},
{
"typ": "roles",
"val": "OurApp.Read"
},
// ...
{
"typ": "ver",
"val": "2.0"
}
]
}
}
```

5. Take a look at the claims that the Function App endpoints receive. It's possible to see this by implementing a function which surfaces roles:

```cs
[FunctionName("GetRoles")]
public static async Task Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "GetRoles")] HttpRequest req
)
{
var roles = req.HttpContext.User?.Claims.Select(c => new { c.Type, c.Value });

return new OkObjectResult(JsonConvert.SerializeObject(roles));
}
```
Which will then be accessed at the static web app's `/api/GetRoles` endpoint:

```json
[
{
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
"Value": "d9178465-3847-4d98-9d23-b8b9e403b323"
},
{
"Type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
"Value": "johnny_reilly@hotmail.com"
},
{
"Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"Value": "authenticated"
},
{
"Type": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
"Value": "anonymous"
}
]
```

At first look, this seems great; we have claims! But when we look again we realise that we have far less claims than we might have hoped for. Crucially, our custom claims / app roles like `OurApp.Read` are missing.

**Expected behavior**

Where a Static Web App has a linked Function App, the Function App should receive a user's App Roles custom claims in calls to API endpoints, in the same way they do at the SWA's `./auth/me` endpoint. Not just UserRoles.

__Why is this important?__

In a word: authorisation. App Roles custom claims are typically used to apply authorisation against applications. Without this in place people have to handroll an authorisation mechanism. The methods they come up with can be insecure and often do not scale.

**Device info (if applicable):**

N/A

**Additional context**

I'd be happy to demo this directly and share code. I'm working with Warren Joubert of Microsoft on a workaround for this and understand this to be a general problem that users are experiencing. It would be tremendous to get this remedied.

[Writing this problem up here, with a workaround - ideally this shouldn't be needed](https://github.com/johnnyreilly/blog.johnnyreilly.com/pull/328)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.