我尝试使identityServer4外部注销功能正常工作。但是有一个错误我无法解决(登录工作很棒)。如果我在注销时点击我的SPA(隐式流),它会重定向到注销端点(idsvr4)但是我收到一个错误: NullReferenceException:未将对象引用设置为对象的实例。
在此行的accountController注销功能中:await _persistedGrantService.RemoveAllGrantsAsync(subjectId, "xxx");
并且该行:return await Logout(new LogoutViewModel { LogoutId = logoutId });
这是我的AccountController注销功能:
/// <summary>
/// Show logout page
/// </summary>
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Logout(string logoutId)
{
if ( User.Identity.IsAuthenticated == false)
{
// if the user is not authenticated, then just show logged out page
return await Logout(new LogoutViewModel { LogoutId = logoutId });
}
var context = await _interaction.GetLogoutContextAsync(logoutId);
if (context?.ShowSignoutPrompt == false)
{
// it´s safe to automatically sign-out
return await Logout(new LogoutViewModel { LogoutId = logoutId });
}
// show the loutout promp. this presents attacks where the user
// is automatically signed out by another malicius web page
var vm = new LogoutViewModel
{
LogoutId = logoutId
};
return View(vm);
}
//
// POST: /Account/Logout
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Logout(LogoutViewModel model)
{
var idp = User?.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
var subjectId = HttpContext.User.Identity.GetSubjectId();
if ( idp != null && idp != IdentityServerConstants.LocalIdentityProvider)
{
if (model.LogoutId == null)
{
model.LogoutId = await _interaction.CreateLogoutContextAsync();
}
string url = "/Account/Logout?logoutId=" + model.LogoutId;
try
{
await HttpContext.Authentication.SignOutAsync(idp, new AuthenticationProperties { RedirectUri = url });
}
catch(NotSupportedException)
{
}
}
// delete authentication cockie
await _signInManager.SignOutAsync();
// set this so UI rendering sees an anonymous user
HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
// get context information (client name, post logout redirect uri and iframe for federated signout)
var logout = await _interaction.GetLogoutContextAsync(model.LogoutId);
var vm = new LoggedOutViewModel
{
PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,
ClientName = logout?.ClientId,
SignOutIframeUrl = logout?.SignOutIFrameUrl
};
await _persistedGrantService.RemoveAllGrantsAsync(subjectId, "xxx");
return Redirect("localhost:5000/index.html");
// return View("LoggedOut", vm);
}
带身份验证的Staartup.cs
public void ConfigureServices(IServiceCollection services)
{
//services.ConfigureDapperConnectionProvider<SqlServerConnectionProvider>(Configuration.GetSection("DapperIdentity"))
// .ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography"))
// .ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false }); //Change to True to use Transactions in all operations
services.ConfigureDapperConnectionProvider<MySqlConnectionProvider>(Configuration.GetSection("DapperIdentity"))
.ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography"))
.ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false }); //Change to True to use Transactions in all operations
// services.ConfigureDapperConnectionProvider<PostgreSqlConnectionProvider>(Configuration.GetSection("DapperIdentity"))
// .ConfigureDapperIdentityCryptography(Configuration.GetSection("DapperIdentityCryptography"))
// .ConfigureDapperIdentityOptions(new DapperIdentityOptions { UseTransactionalBehavior = false }); //Change to True to use Transactions in all operations
services.AddIdentity<CustomUser, CustomRole>(x =>
{
x.Password.RequireDigit = false;
x.Password.RequiredLength = 1;
x.Password.RequireLowercase = false;
x.Password.RequireNonAlphanumeric = false;
x.Password.RequireUppercase = false;
})
// .AddDapperIdentityFor<PostgreSqlConfiguration>()
//.AddDapperIdentityFor<SqlServerConfiguration>()
.AddDapperIdentityFor<MySqlConfiguration>()
.AddDefaultTokenProviders();
services.AddMvc();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryPersistedGrants()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddAspNetIdentity<CustomUser>()
.AddProfileService<ProfileService>();
services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "http://localhost:4200";
options.ApiName = "api1";
options.SupportedTokens = SupportedTokens.Both;
});
}
有谁知道这个错误是什么?
*** **** UPDATE 我自己解决了这个问题