Search code examples
asp.netasp.net-coreauthorizationopenid-connectasp.net-authorization

Missing `aud` claim in ASP.NET core policy check prevents authorization, but it is in id token


I'm working through the example application here: https://github.com/FusionAuth/fusionauth-example-asp-netcore and am running into a situation where the claim is present in the token issued by the OIDC provider, but is not available to the authorization policy I'm creating.

I'm using .NET core 3.1 and these are my dependencies:

  <ItemGroup>
    <PackageReference Include="IdentityModel.AspNetCore" Version="1.0.0-rc.4.1" />
    <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.3" />
  </ItemGroup>

Rather than checking the applicationId as the example does, I want to check the aud claim at this point: https://github.com/FusionAuth/fusionauth-example-asp-netcore/blob/master/SampleApp/Startup.cs#L35

So the code adding the policy looks like:

         // Configure your policies
            services.AddAuthorization(options =>
                options.AddPolicy("Registered",
                policy => policy.RequireClaim("aud", Configuration["SampleApp:ClientId"])));

But the policy fails, and I'm denied access to the secure page. If I change the policy to look like this:

         // Configure your policies
            services.AddAuthorization(options =>
                options.AddPolicy("Registered",
                policy => policy.RequireClaim("sub")));

It succeeds, showing me the secured page (so I have a sub claim).

I have tried the following to debug this:

  • Ensured the OIDC server generates a JWT with the aud claim (the server is FusionAuth if that matters). It does.
  • Changing the policy so any aud claim is authorized. I'm still prevented from viewing the secure page.
  • Adding various events to options.events in the AddOpenIdConnect method ( https://github.com/FusionAuth/fusionauth-example-asp-netcore/blob/master/SampleApp/Startup.cs#L47 ). I added OnTokenResponseReceived and OnTokenValidated and printed out the token claims received. In both these cases, I see the aud claim.

Is there some filtering going on? I have googled around and haven't seen anything. There's a recommendation to add this line:

JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

because the framework code does some claim mapping, but that didn't seem to help with my issue.

Any suggestions on what I can do to ensure the aud claim is checked by the authorization service would be welcome.


Solution

  • So the issue is that there are default claim actions in the OIDC options.

    https://github.com/dotnet/aspnetcore/blob/v3.1.19/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs shows, for 3.1.x:

    // ...
                ClaimActions.DeleteClaim("nonce");
                ClaimActions.DeleteClaim("aud");
                ClaimActions.DeleteClaim("azp");
                ClaimActions.DeleteClaim("acr");
    // more claims modification
    

    If you delete the relevant claim action:

    options.ClaimActions.Remove("aud");
    

    The aud claim is then available to the policy.

    More on claim actions: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.oauth.claims.claimactioncollection?view=aspnetcore-3.1