.net core .net core 2.2多承载令牌身份验证方案
我目前正在尝试在.net core 2.2应用程序中使用2种不同的承载令牌。我想使用Identity Server令牌和Azure AD承载令牌。根据微软的说法,这是可能的,但我没有成功地让它工作 我将Identity Server令牌作为“默认”身份验证,然后是AzureAD令牌,如上述链接中所述:.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 => {
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();
});