Azure AD Claims with Static Web Apps and Azure Functions (Authorization)
- 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:

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.