。net核心2.2多承载令牌认证方案

问题描述 投票:0回答:1

我目前正在.net核心2.2应用程序中尝试使用2个不同的承载令牌。我想使用Identity Server令牌和Azure AD承载令牌。根据Microsoft的说法,这是可能的(https://docs.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme?view=aspnetcore-2.2),但我无法成功使其正常运行。

我将Identity Server令牌作为“默认”身份验证,后跟上述链接中记录的AzureAD令牌:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = newTokenValidationParameters
        {
            ValidateAudience = true,
            ValidateIssuer = true,
            ValidateLifetime = true,
            ClockSkew = ClockSkew
        };
        o.Audience = Audience;
        o.Authority = IdentityIssuer;
        o.RequireHttpsMetadata = true;
    })
    .AddJwtBearer("AzureAd",o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
        };
        o.Audience = AudienceUri;
        o.Authority = Authority
    });

Identity Server令牌已按预期验证;但是Azure AD令牌没有。它们似乎总是命中默认的Bearer令牌处理程序。

.net-core jwt azure-active-directory bearer-token .net-core-2.2
1个回答
0
投票

尝试这样的事情(我有2个身份验证方案。一个用于AAD,一个用于自定义Bearer身份验证)

 var url = new MongoUrl(mongoSettings.ConnectionString);

            var client = new MongoClient(url);

            var database = client.GetDatabase(url.DatabaseName);

            services.AddIdentity<ApplicationUser, ApplicationRole>(options =>

            {
                options.Password.RequireDigit = true;

                options.Password.RequiredLength = 6;

                options.Password.RequireNonAlphanumeric = false;

                options.Password.RequireUppercase = true;

                options.Password.RequireLowercase = true;

                // Lockout settings

                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);

                options.Lockout.MaxFailedAccessAttempts = 0;

                // ApplicationUser settings

                options.User.RequireUniqueEmail = false;

                //options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_";
            }).RegisterMongoStores<ApplicationUser, ApplicationRole>(

                p => database.GetCollection<ApplicationUser>("AspNetUsers"),

                p => database.GetCollection<ApplicationRole>("AspNetRoles"))

              .AddDefaultTokenProviders();

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims





            var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(appConfiguration.Key));

            var tokenValidationParameters = new TokenValidationParameters

            {
                //RequireExpirationTime = true,

                //RequireSignedTokens = true,

                //ValidateIssuerSigningKey = true,

                IssuerSigningKey = signingKey,

                ValidateIssuer = false,

                ValidIssuer = appConfiguration.SiteUrl,

                ValidateAudience = false,

                ValidAudience = appConfiguration.SiteUrl,

                //ValidateLifetime = true,

                ClockSkew = TimeSpan.Zero
            };

            services.AddAuthentication(options =>

            {
                //options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer("AAD", options =>
              {
                  //options.Audience = appConfiguration.SiteUrl;

                  //options.ClaimsIssuer = appConfiguration.SiteUrl;
                  options.IncludeErrorDetails = true;
                  options.Authority = "https://sts.windows.net/800859e2-e8c3-4842-b31a-3b3727070cb6/v2.0";
                  options.Audience = "5e2ddaf2-2ed3-4829-bbe8-9aa127a754ef";
                  options.SaveToken = true;

                  options.Events = new JwtBearerEvents()
                  {
                      OnMessageReceived = context =>
                      {
                          if ((context.Request.Path.Value.StartsWith("/videohub")
                              //|| context.Request.Path.Value.StartsWith("/looney")
                              //|| context.Request.Path.Value.StartsWith("/usersdm")
                             )
                              && context.Request.Query.TryGetValue("token", out StringValues token)
                          )
                          {
                              context.Token = token;
                          }

                          return Task.CompletedTask;
                      },
                      OnAuthenticationFailed = context =>
                      {
                          //TODO:
                          return Task.FromResult(0);
                      },
                      OnTokenValidated = context =>
                      {
                          //At this point, the security token has been validated successfully and a ClaimsIdentity has been created
                          var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;

                          //get username
                          var preferred_username = claimsIdentity.Claims.ToList().Where(c => c.Type == "preferred_username").Select(c => c.Value).FirstOrDefault();

                          var username = !string.IsNullOrEmpty(preferred_username) ? preferred_username : claimsIdentity.Claims.ToList().Where(c => c.Type == "upn").Select(c => c.Value).FirstOrDefault();

                          //add your custom claims here
                          var serviceProvider = services.BuildServiceProvider();
                          var userservice = serviceProvider.GetService<IUsersService>();

                          var us = userservice.Find(xx => xx.UserName == username);
                          if (us == null) return Task.FromResult(0);

                          // ADD SCHEMA (so we know which kind of token is .. from AZURE ACTIVE DIRECOTY .. OR CUSTOM)
                          // TO RETIRVE THE SCHEDA ..--> //var result = User.Claims.Where(c=>c.Type=="schema").FirstOrDefault().Value;
                          claimsIdentity.AddClaim(new Claim("schema", "AAD"));

                          //GET ROLES FROM DB
                          if (us != null && us.Roles.Any())
                          {
                              //add THEM
                              us.Roles.ForEach(rr =>
                               {
                                   claimsIdentity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, rr.ToUpper()));
                               });
                          }
                          else
                          {
                              //OR ADD A DEFAULT ONE
                              claimsIdentity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, Constant.ROLES.Dipendente));
                          }

                          // add MONGDB Id as ClaimTypes.NameIdentifier
                          claimsIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, us.Id));

                          return Task.FromResult(0);
                      }
                  };
              }).AddJwtBearer("CUSTOM", options =>
               {
                   //options.Audience = appConfiguration.SiteUrl;

                   //options.ClaimsIssuer = appConfiguration.SiteUrl;

                   options.TokenValidationParameters = tokenValidationParameters;

                   options.SaveToken = true;
                   options.Events = new JwtBearerEvents()
                   {
                       OnMessageReceived = context =>
                       {
                           if ((context.Request.Path.Value.StartsWith("/videohub")
                              //|| context.Request.Path.Value.StartsWith("/looney")
                              //|| context.Request.Path.Value.StartsWith("/usersdm")
                              )
                               && context.Request.Query.TryGetValue("token", out StringValues token)
                           )
                           {
                               context.Token = token;
                           }

                           return Task.CompletedTask;
                       },
                       OnAuthenticationFailed = context =>
                       {
                           //TODO:
                           return Task.FromResult(0);
                       },
                       OnTokenValidated = context =>
                       {
                           //At this point, the security token has been validated successfully and a ClaimsIdentity has been created
                           var claimsIdentity = (ClaimsIdentity)context.Principal.Identity;

                           //add your custom claims here

                           // ADD SCHEMA (so we know which kind of token is .. from AZURE ACTIVE DIRECOTY .. OR CUSTOM)
                           claimsIdentity.AddClaim(new Claim("schema", "CUSTOM"));

                           return Task.FromResult(0);
                       }
                   };
               });

然后将您的Controller标记类或方法标记为:

   [Route("api/[controller]")]
    [ApiController]
    [Authorize(AuthenticationSchemes = "AAD,CUSTOM")] //<-- yours schema
    public class AccountController : Controller
    {
 // ...
}

希望对您有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.