我正在关注IdentityServer4 Quickstart project,以便快速了解它的实施方式。我的Startup.cs
接近相同,我对AccountController.cs
类的实现或多或少相同,依此类推。
但是,似乎存在某种与本地身份验证cookie处理方式的低级冲突。
1)在启动时,我不会调用app.UseAuthentication()
,因为IdentityServer稍后会设置它。我已经逐字逐句地从快速启动项目中复制services.AddAuthentication()
,但我仍然遇到问题。
登录时,Quickstart项目会生成两个Cookie:一个Forgery Validation Cookie和一个名为idsrv
的Cookie。项目中没有任何地方明确定义这样做。
然而,当我运行它的实现时,我得到三个cookie:伪造验证cookie,idsrv.session
cookie和.AspNetCore.Identity.Application
cookie。我可以强制ASP.NET命名cookie' idsrv'但是.session cookie的存在让我相信它没有使用正确的方案。
2)当我尝试通过调用HttpContext.SignOutAsync()
注销时,cookie不会被删除而且没有任何反应:它保持登录状态。我发现了类似问题的问题,但这些似乎是a)实现了外部身份验证和b)实现可能会覆盖注销网址的重定向。我两个都没做。
我的登录实施:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login( LoginInputModel model, string action )
{
var context = await _interactionService.GetAuthorizationContextAsync( model.ReturnUrl );
if( action != "Login" )
{
if( context != null )
{
// Handle a cancelled login
await _interactionService.GrantConsentAsync( context, ConsentResponse.Denied );
}
else
return Redirect( "~/" );
}
var errors = ModelState.Values.SelectMany( v => v.Errors );
if( ModelState.IsValid )
{
var user = await _userManager.FindByNameAsync( model.Username );
if( user != null && await _userManager.CheckPasswordAsync( user, model.Password ) )
{
await _eventService.RaiseAsync( new UserLoginSuccessEvent( user.UserName, user.Id, user.UserName ) );
//Handle RememberMe Checkbox
AuthenticationProperties props = null;
if( model.RememberMe )
{
props = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.Add( Config.AccountRememberMeDuration ),
};
}
//Issue Auth Cookie
await HttpContext.SignInAsync( user.Id, user.UserName, props );
if( _interactionService.IsValidReturnUrl( model.ReturnUrl ) || Url.IsLocalUrl( model.ReturnUrl ) )
return Redirect( model.ReturnUrl );
return Redirect( "~/" );
}
//If we made it this far, the authentication failed
await _eventService.RaiseAsync( new UserLoginFailureEvent( model.Username, "Invalid Credentials" ) );
ModelState.AddModelError( "", "Invalid Credentials" );
}
//Display form with error message
model.Password = string.Empty;
return View( model );
}
我的退出实施:
[HttpGet]
public async Task Logout( LogoutInputModel model )
{
if( User?.Identity.IsAuthenticated == true )
{
await HttpContext.SignOutAsync();
await _eventService.RaiseAsync( new UserLogoutSuccessEvent( User.GetSubjectId(), User.GetDisplayName() ) );
}
}
My Startup.cs:
public void ConfigureServices( IServiceCollection services )
{
services.AddMvc();
services.AddIdentityServer()
.AddOperationalStore( options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer( Config.ConnectionString, sqlOptions => sqlOptions.MigrationsAssembly( Config.MigrationsAssembly ) );
options.EnableTokenCleanup = true;
options.TokenCleanupInterval = 30; //Every 30 seconds
} )
.AddConfigurationStore( options =>
{
options.ConfigureDbContext = builder =>
builder.UseSqlServer( Config.ConnectionString, sqlOptions => sqlOptions.MigrationsAssembly( Config.MigrationsAssembly ) );
} )
.AddDeveloperSigningCredential();
services.AddDbContext<CustomUserContext>( builder =>
builder.UseSqlServer( Config.ConnectionString, sqlOptions => sqlOptions.MigrationsAssembly( Config.MigrationsAssembly ) )
);
services.AddIdentity<CustomUser, CustomRole>()
.AddEntityFrameworkStores<CustomUserContext>();
services.AddAuthentication();
}
public void Configure( IApplicationBuilder app, IHostingEnvironment env )
{
if( env.IsDevelopment() )
app.UseDeveloperExceptionPage();
app.UseIdentityServer();
app.UseStaticFiles();
app.UseMvcWithDefaultRoute(); //TODO: Routes
}
我如何调用注销功能:
<div class="account-actions">
@using( Html.BeginForm( "Logout", "Account", FormMethod.Get ) )
{
<input type="submit"
class="account-action-button account-action-logout"
value="Logout" />
}
</div>
答案 0 :(得分:1)
据我所知,您在MVC应用程序中隐藏了IdentityServer,我相信您需要为您的MVC应用程序配置Cookie中间件。您现在在Startup.cs中进行的配置适用于IdentityServer本身。您获得的cookie是IdentityServer的cookie。
在此示例中查看如何配置cookie身份验证+ OIDC: https://github.com/IdentityServer/IdentityServer4.Samples/blob/release/Clients/src/MvcHybrid/Startup.cs
答案 1 :(得分:0)
我有同样的问题。我以为我可以尝试改为致电SignOutAsync( schema )
。通过尝试注销不存在的架构,我收到一条错误消息,其中列出了所支持的架构。其中之一是“ Identity.Application”,并对其进行注销。例如
await this.HttpContext.SignOutAsync( "Identity.Application" );