简体   繁体   中英

Custom claims with SPA, WEBAPI and Identity Server 4 using oidc?

Been banging my head on this for few days.

So I have Identity Server 4 which is my "authentication as a service" a centralized login for all my applications, using ASP.NET Identity for user management.

On my Client side, I am using Angular with oidc-client.js and so far everything is working as expected, I can get user identity token and access token.

For my WebApi(not using .NET Core), I am trying to use UseOpenIdConnectAuthentication so I can add app specific custom claims through it OpenIdConnectAuthenticationNotifications but am getting 401 Unauthorized when calling my API from Angular.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
     ResponseType = "id_token token",
     Scope = "openid profile api1",
     Authority = "http://localhost:61294/",
     ClientId = "api",
     RedirectUri = "http://localhost:56105/sigin-oidc",
     Notifications = new OpenIdConnectAuthenticationNotifications
     {
         AuthorizationCodeReceived = async n =>
         {
             // Ignore, just testing 
             var tokenClient = new TokenClient("http://localhost:61294/connect/token", "mvc");
             var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri);
         },
         SecurityTokenValidated = async n =>
         {
             var userInfoClient = new UserInfoClient(new Uri("http://localhost:61294/connect/userinfo"), n.ProtocolMessage.AccessToken);
             var userInfo = await userInfoClient.GetAsync();

             var nId = new ClaimsIdentity(
                               n.AuthenticationTicket.Identity.AuthenticationType,
                               ClaimTypes.GivenName,
                               ClaimTypes.Role);

             userInfo.Claims.ToList().ForEach(c => nId.AddClaim(new Claim(c.Item1, c.Item2)));

             nId.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken));

             nId.AddClaim(new Claim("Test", "test"));

             n.AuthenticationTicket = new AuthenticationTicket(nId, n.AuthenticationTicket.Properties);
             n.Request.Headers.SetValues("Authorization ", "Bearer ", n.ProtocolMessage.AccessToken);
         },
         SecurityTokenReceived = async n =>
         {
             Debug.WriteLine(n);
         }
     }
 });

I also used the package IdentityServer3.AccessTokenValidation and use app.UseIdentityServerBearerTokenAuthentication which works fine, I was able to call my API with success but I don't see how I could apply my custom claims through this.

Am I approaching this the wrong way using app.UseOpenIdConnectAuthentication for web api? Any guidance on this would be much appreciated.

OK, now I got what is your problem. The Startup.cs configuration that you have posted is a startup for a client, but you are trying to use it in an api resource.

A startup for an api resource should look like the one here (I'm showing the one for Identity server 3, because I understood that your API is a .Net Framework one). This is why the code is never reached (what you mentioned in the comment).

Honestly, I'm pretty sure, that you can't achieve what you are aiming for - adding a custom claim to the token in the api resource. The api resource is made to be consumed, and read the already provided claims (most of the time authorization for the api is done based on the claims).

Otherwise, all the other things you've done are correct. You should use IdentityServer3.AccessTokenValidation for .Net Framework clients and api's (no problem, that the token issuer is IDS4).

Most likely this is the reason that you receive the 401. You have not set properly the authority for the api. I hope that this helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM