我正在尝试使用多个身份验证提供程序-一个非常简单的cookie身份验证,并打开了id连接。我的大多数用户将使用简单的cookie身份验证。但是,一些用户已经在开放ID连接系统上,我希望他们能够连接。我可以使其中一个工作,但不能同时工作。添加openid connect会覆盖其他cookie系统。我怎样才能使它们彼此和谐地玩耍。可以接受的解决方案是,Open ID连接不重定向到登录屏幕,而用户将需要手动登录。
这是我的启动班:
public class Startup
{
public Startup(IConfiguration configuration) => this.Configuration = configuration;
public IConfiguration Configuration { get; }
private CultureInfo[] supportedCultures;
private CultureInfo[] SupportedCultures => this.supportedCultures ??= new[] { new CultureInfo("en-US") };
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting(options =>
{
options.LowercaseUrls = true;
options.AppendTrailingSlash = false;
options.LowercaseQueryStrings = true;
});
// Add MVC with feature folders
services.AddMvc(opt => opt.Filters
.Add(typeof(DbContextTransactionFilter)))
.AddFeatureFolders()
.AddViewLocalization()
.AddDataAnnotationsLocalization();
// Add HTTP Context to DI Container
services.AddHttpContextAccessor();
// Add localization
services.AddLocalization();
services.Configure<RequestLocalizationOptions>(options =>
{
// Just supporting English right now
options.DefaultRequestCulture = new RequestCulture("en-US", "en-US");
// You must explicitly state which cultures your application supports.
// These are the cultures the app supports for formatting
// numbers, dates, etc.
options.SupportedCultures = this.SupportedCultures;
// These are the cultures the app supports for UI strings,
// i.e. we have localized resources for.
options.SupportedUICultures = this.SupportedCultures;
});
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(options =>
{
options.AccessDeniedPath = "/request-access";
options.ExpireTimeSpan = TimeSpan.FromDays(14);
options.LoginPath = "/request-access";
options.LogoutPath = "/request-access";
options.Cookie.Name = "AMGAuthCookie";
})
.AddOpenIdConnect("oidc", options =>
{
options.ClientId = "MyClientID";
options.Authority = "https://myidentityserver.com/";
options.RequireHttpsMetadata = false;
options.GetClaimsFromUserInfoEndpoint = true;
options.ResponseType = "code token";
options.Scope.Clear();
options.Scope.Add("openid");
options.Scope.Add("sitecore.profile");
options.Scope.Add("offline_access");
options.Scope.Add("sitecore.profile.api");
options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = JwtClaimTypes.Name,
RoleClaimType = JwtClaimTypes.Role,
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
var pageOptions = new DeveloperExceptionPageOptions { SourceCodeLineCount = 10 };
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage(pageOptions);
}
else
{
app.UseStatusCodePagesWithReExecute("/error/{0}");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
app.UseCookiePolicy(cookiePolicyOptions);
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = this.SupportedCultures,
SupportedUICultures = this.SupportedCultures
});
app.UseEndpoints(endpoints => endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"));
}
}
答案 0 :(得分:1)
ForwardDefaultSelector
services
.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = "dynamic";
})
.AddPolicyScheme("dynamic", "Cookie or JWT", options =>
{
options.ForwardDefaultSelector = context =>
{
var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
var isApiPath = context.Request.Path.StartsWithSegments("/api");
if (authHeader?.StartsWith("Bearer ") || isApiPath)
{
return JwtBearerDefaults.AuthenticationScheme;
}
return CookieAuthenticationDefaults.AuthenticationScheme;
};
})
.AddJwtBearer(o =>
{
o.Authority = Configuration["JWT:Authentication:Authority"];
o.Audience = Configuration["JWT:Authentication:ClientId"];
o.SaveToken = true;
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
...
}
答案 1 :(得分:0)
我通过保留上面的Startup.cs来解决了这个问题,但是随后更改了我对控制器的授权方式。授权后,我会设定一个特定的方案。 Cookie方案可以使我登录cookie,OpenIdConnect方案可以使我登录OpenIdConnect。在构建应用程序时,我可能需要花些时间来处理资源,但这似乎可以解决问题。幸运的是,通过cookie登录的用户与通过OpenIDConnect登录的用户之间存在业务逻辑差异。
[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)]