У меня есть два основных веб-приложения asp.net (использующих один и тот же идентификатор регистрации приложения), защищенных с помощью Azure AD. Если я вхожу в один, поток аутентификации прерывается для другого, но не наоборот.
Я думаю, что это как-то связано с куки-файлами аутентификации и что приложение Admin выбирает приложение, созданное для приложения Portal. Если это предположение верно, как я могу убедиться, что приложения не используют куки друг друга?
Настройка
- Приложение 1, Портал с разветвленным конвейером
- Приложение 2, страница администратора
Контрольные примеры
OK : Load Admin and log in
OK : Load Portal and log in
NOK: Load the Portal and log in, navigate to Admin (auth loop)
NOK: Load Admin and log in,
navigate to Portal (credentials not requested, reusing the cookie i guess),
reload Admin (auth loop)
Приложение Admin сообщает о следующей ошибке и создает цикл перенаправления аутентификации.
Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler: Информация: файлы cookie не были аутентифицированы. Сообщение об ошибке: сбой снятия защиты с билета
Startup.cs для приложения Portal
public class Startup
{
public Startup( IConfiguration configuration )
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices( IServiceCollection services )
{
services.AddAuthentication( o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}
).AddOpenIdConnect( o =>
{
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.ClientId = "same-for-both-apps";
o.CallbackPath = "/portal/signin-oidc";
o.Authority = "https://login.windows.net/common";
o.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = ClaimTypes.Role,
ValidateIssuer = false,
};
}
).AddCookie( options =>
{ options.AccessDeniedPath = new PathString( "/Account/AccessDenied" ); } );
services.AddMvc( o =>
{
o.Filters.Add( new AuthorizeFilter(
new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build() ) );
}
).SetCompatibilityVersion( CompatibilityVersion.Version_2_2 );
}
public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
app.MapWhen( IsTargetingPortal, HandlePortalRequest );
app.Run( async ctx =>
{
await ctx.Response.WriteAsync( "Default: info page" );
} );
}
bool IsTargetingPortal( HttpContext ctx )
{
return ctx.Request.Path == "/portal/signin-oidc" ||
ctx.Request.Path == "/portal" ||
ctx.Request.Host.Host.StartsWith( "portal." );
}
void HandlePortalRequest( IApplicationBuilder builder )
{
builder.UseAuthentication();
builder.UseMvc( routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}" );
} );
}
}
Startup.cs для приложения Admin
public class Startup
{
public Startup( IConfiguration configuration )
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices( IServiceCollection services )
{
services.AddAuthentication( o =>
{
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
}
).AddOpenIdConnect( o =>
{
o.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.ClientId = "same-for-both-apps";
o.Authority = "https://login.windows.net/common";
o.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = ClaimTypes.Role,
ValidateIssuer = false,
};
}
).AddCookie( options =>
{ options.AccessDeniedPath = new PathString( "/Account/AccessDenied" ); } );
services.AddMvc( o =>
{
o.Filters.Add( new AuthorizeFilter(
new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build() ) );
}
).SetCompatibilityVersion( CompatibilityVersion.Version_2_2 );
}
public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
app.UsePathBase( "/admin" );
if( env.IsDevelopment() )
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler( "/Error" );
app.UseHsts();
}
app.UseAuthentication();
app.UseMvc();
}
}