.net core .net core 2.2多承载令牌身份验证方案

.net core .net core 2.2多承载令牌身份验证方案,.net-core,jwt,azure-active-directory,bearer-token,.net-core-2.2,.net Core,Jwt,Azure Active Directory,Bearer Token,.net Core 2.2,我目前正在尝试在.net core 2.2应用程序中使用2种不同的承载令牌。我想使用Identity Server令牌和Azure AD承载令牌。根据微软的说法,这是可能的,但我没有成功地让它工作 我将Identity Server令牌作为“默认”身份验证,然后是AzureAD令牌,如上述链接中所述: services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(o => {

我目前正在尝试在.net core 2.2应用程序中使用2种不同的承载令牌。我想使用Identity Server令牌和Azure AD承载令牌。根据微软的说法,这是可能的,但我没有成功地让它工作

我将Identity Server令牌作为“默认”身份验证,然后是AzureAD令牌,如上述链接中所述:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters
        {
            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
    });

身份服务器令牌按预期进行验证;但是Azure广告代币没有。它们似乎总是命中默认的承载令牌处理程序。

尝试类似的方法(我有两个身份验证方案;一个用于AAD,另一个用于自定义承载身份验证)

var url=newmongourl(mongoSettings.ConnectionString);//我使用MONGODB作为数据库,但是你可以选择你想要的
var client=新的MongoClient(url);
var database=client.GetDatabase(url.DatabaseName);
服务.附加性(选项=>
{
options.Password.RequireDigit=true;
options.Password.RequiredLength=6;
options.Password.RequireNonAlphanumeric=false;
options.Password.RequireUppercase=true;
options.Password.RequireLowercase=true;
//锁定设置
options.Lockout.DefaultLockoutTimeSpan=TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts=0;
//应用程序用户设置
options.User.RequireUniqueEmail=false;
//options.User.AllowedUserNameCharacters=”abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@.-_";
}).RegisterMongstores(
p=>database.GetCollection(“AspNetUsers”),
p=>database.GetCollection(“AspNetRoles”))
.AddDefaultTokenProviders();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();//=>删除默认索赔
var-signingKey=new-SymmetricSecurityKey(Encoding.ASCII.GetBytes(appConfiguration.Key));
var tokenValidationParameters=新的tokenValidationParameters
{
//RequireExpirationTime=true,
//RequireSignedTokens=true,
//validateSuersigningKey=true,
IssuerSigningKey=签名密钥,
validateisuer=false,
ValidisUser=appConfiguration.SiteUrl,
ValidateAudience=false,
Validudience=appConfiguration.SiteUrl,
//ValidateLifetime=true,
时钟偏移=时间跨度0
};
services.AddAuthentication(选项=>
{
//options.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme
options.DefaultScheme=JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(“AAD”,选项=>
{
//options.acquisition=appConfiguration.SiteUrl;
//options.ClaimsIssuer=appConfiguration.SiteUrl;
options.IncludeErrorDetails=true;
选项。权限=”https://sts.windows.net/800859e2-e8c3-4842-b31a-3b3727070cb6/v2.0";
选项。受众=“5e2ddaf2-2ed3-4829-bbe8-9aa127a754ef”;
options.SaveToken=true;
options.Events=newjwtbearerevents()
{
OnMessageReceived=上下文=>
{
if((context.Request.Path.Value.StartsWith(“/videohub”)
//||context.Request.Path.Value.StartsWith(“/looney”)
//||context.Request.Path.Value.StartsWith(“/usersdm”)
)
&&context.Request.Query.TryGetValue(“令牌”,out-StringValues令牌)
)
{
context.Token=Token;
}
返回Task.CompletedTask;
},
OnAuthenticationFailed=上下文=>
{
//待办事项:
返回Task.FromResult(0);
},
OnTokenValidated=上下文=>
{
//此时,已成功验证安全令牌,并创建了ClaimSideEntity
var claimsIdentity=(claimsIdentity)context.Principal.Identity;
//获取用户名
var preferred_username=claimsIdentity.Claims.ToList()。其中(c=>c.Type==“preferred_username”)。选择(c=>c.Value)。FirstOrDefault();
var username=!string.IsNullOrEmpty(首选用户名)?首选用户名:claimsIdentity.Claims.ToList()。其中(c=>c.Type==“upn”)。选择(c=>c.Value)。FirstOrDefault();
//在此处添加您的自定义索赔
var serviceProvider=services.BuildServiceProvider();
var userservice=serviceProvider.GetService();
var us=userservice.Find(xx=>xx.UserName==UserName);
if(us==null)返回Task.FromResult(0);
//添加架构(以便我们知道哪种令牌是来自AZURE ACTIVE DIRECTORY的或自定义的)
//要检索架构..-->//var result=User.Claims.Where(c=>c.Type==“SCHEMA”).FirstOrDefault().Value;
新增权利要求(新权利要求(“模式”、“AAD”);
//从数据库获取角色
if(us!=null&&us.Roles.Any())
{
//添加它们
us.Roles.ForEach(rr=>
{
索赔实体。添加
var url = new MongoUrl(mongoSettings.ConnectionString); // I'm using MONGODB as databse ..but you can choose what you want 

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 DIRECTORY .. OR CUSTOM)
                          // TO RETRIEVE THE SCHEMA ..--> //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()
                   {

                       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);
                       }
                   };
               });
   [Route("api/[controller]")]
    [ApiController]
    [Authorize(AuthenticationSchemes = "AAD,CUSTOM")] //<-- yours schema
    public class AccountController : Controller
    {
 // ...
}
services.AddAuthorization(options => { 
        options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme, "AzureAD")
           .RequireAuthenticatedUser()
           .Build();
 if (arg.HttpContext.User.Identity.IsAuthenticated)
    {
       return Task.CompletedTask;
    }
      app.Use(async (context, next) =>
            {
                if (!context.User.Identity.IsAuthenticated)
                {
                    var result = await context.AuthenticateAsync("AzureAD");
                    if (result?.Principal != null)
                    {
                        context.User = result.Principal;
                    }
                }

                await next.Invoke();
            });