我为使用 AspNetCore Identity 的现有应用程序创建了一个 OpenIddict 身份验证服务器。登录过程工作得很好,但注销过程会导致我的应用程序和身份验证服务器之间出现无限循环。这是我的设置:
Startup.cs
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme;
options.DefaultSignOutScheme = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, options =>
{
options.SignInScheme = IdentityConstants.ApplicationScheme;
options.Authority = "https://localhost:44395";
options.ClientId = "myclient";
options.ResponseType = OpenIdConnectResponseType.Code;
options.Scope.Add(Scopes.Profile);
options.Scope.Add(Scopes.Email);
options.CallbackPath = "/signin-oidc";
options.SaveTokens = true;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = Claims.Name
};
options.GetClaimsFromUserInfoEndpoint = true;
options.SignedOutRedirectUri = "/Account/Login";
});
我的
Logout()
中的AccountController
方法:
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return SignOut(authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
}
我的身份验证服务器的启动:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);
services.AddControllersWithViews();
services.AddRazorPages();
services.AddDbContext<UserDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("connection-dev"));
options.UseOpenIddict();
});
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<UserDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(10);
options.Cookie.HttpOnly = true;
options.Cookie.SameSite = SameSiteMode.None;
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
services.Configure<IdentityOptions>(options =>
{
options.ClaimsIdentity.UserNameClaimType = Claims.Name;
options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
options.ClaimsIdentity.RoleClaimType = Claims.Role;
options.ClaimsIdentity.EmailClaimType = Claims.Email;
options.SignIn.RequireConfirmedAccount = false;
});
services.AddCors(options =>
{
options.AddPolicy("AllowMyOrigins",
builder =>
{
builder
.AllowCredentials()
.WithOrigins(
["http://localhost:5000"])
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore()
.UseDbContext<UserDbContext>();
})
.AddServer(options =>
{
options.SetAuthorizationEndpointUris("connect/authorize")
.SetIntrospectionEndpointUris("connect/introspect")
.SetLogoutEndpointUris("connect/logout")
.SetTokenEndpointUris("connect/token")
.SetUserinfoEndpointUris("connect/userinfo")
.SetVerificationEndpointUris("connect/verify");
options.AllowAuthorizationCodeFlow()
.AllowRefreshTokenFlow();
options.RegisterScopes(Scopes.Email, Scopes.Profile, Scopes.Roles);
options.AddDevelopmentEncryptionCertificate()
.AddDevelopmentSigningCertificate();
options.UseAspNetCore()
.EnableAuthorizationEndpointPassthrough()
.EnableLogoutEndpointPassthrough()
.EnableTokenEndpointPassthrough()
.EnableUserinfoEndpointPassthrough()
.EnableStatusCodePagesIntegration();
})
.AddValidation(options =>
{
options.UseLocalServer();
options.UseAspNetCore();
});
还有
AuthorizationController.Logout()
:我删除了同意注销部分,因此它应该立即将用户注销。
[HttpGet("~/connect/logout")]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
return SignOut(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
}
post_logout_redirect_uri 是 http://localhost:5000/signout-callback-oidc。 当我尝试注销时,它进入无限循环,如下所示: 我想我希望它在注销时返回到身份验证服务器的登录页面。我绝对不希望它永远循环下去:)。 以下是表格形式的请求: |方法|端点 |状态代码 |类型 |来源 | |--------|----------|-------------|-----|-------- | |获取 | http://localhost:5000/帐户/注销| 302 | 302 xhr / 重定向 |用户配置文件.component.ts:42 | |获取 | post_logout_redirect_uri=http%3A%2F%2Flocal…Ib3Ak&x-client-SKU=ID_NET8_0&x-client-ver=7.2.0.0 | 注销? 302 | 302 xhr / 重定向 | - | |获取 | https://localhost:44395/connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fsignout-callback-oidc&id_token_hint=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIzMEYxN0VGRkVBM0RERTFGNTYzNkRCMDcwNzA1NDYxRDExRjk0 RkEiLCJ4NXQiOiJJdzhYN182ajNlSDFZMjJ3Y0hCVVlkRWZsUG8iLCJ0eXAiOiJKV1QifQ..sTuSjQCxqh89nEqOn-zfykkLiZoB_UOCbE8FHG5_v8sjJHx5Ytn6YxONpQenIjZggDLvXSBs4MBN 9oRe2VqQpkFO2i1RBaCIiCfmyYY4YDQ4EiAr3R7Z9TpJ_W-4rHkczlHYsU9WT9OtOfXUOPy1uHQPIRgrDHBScZVMo0Uz0Q9BLU2d0Dg3rs3esRxA3MJJn3fedqQoSYlnBFdRxo-4-szu4krldn4mhkns- ua96pCQWQwIGetFKzhV2MDOzFF5vj38mjwKNw80v4dP-H8Prq1Q8LuzCIXyra8USx6WQVYaQVVb3c_5FxEVCaBCxB-XaZN8lP3Ajw9Ed-KWaXcdgA&状态=CfDJ8DwhaUXmuCROpCgfCLIYTwyHz6Z_WecMr8WjPz6O6F48TU3RrqurGDWG2WoOY-Y52iZP5ykUZFDFVFqOL4j8yiARGAVHDLii8h4JD6zFXKf82zGODbRgPYNex7wH8okYB4LUyfQqxyNGjJ9A4l Ib3Ak&x-client-SKU=ID_NET8_0&x-client-ver=7.2.0.0 | 204 | 204飞行前 |飞行前 | |获取 | post_logout_redirect_uri=http%3A%2F%2Flocal…Ib3Ak&x-client-SKU=ID_NET8_0&x-client-ver=7.2.0.0 | 注销? 302 | 302 xhr / 重定向 |退出 | |获取 |状态=CfDJ8DwhaUXmuCROpCgfCL…zFXKf82zGODbRgPYNex7wH8okYB4LUyfQqxyNGjJ9A4lIb3Ak | 注销回调-oidc? http://localhost:5000/signout-callback-oidc?state=CfDJ8DwhaUXmuCROpCgfCLIYTwyHz6Z_WecMr8WjPz6O6F48TU3RrqurGDWG2WoOY-Y52iZP5ykUZFDFVFqOL4j8yiARGAVHDLii8h4JD6zFXKf82zGODbRgPYNex7wH 8okYB4LUyfQqxyNGjJ9A4lIb3Ak | 204 | 204飞行前 |飞行前 | |获取 |状态=CfDJ8DwhaUXmuCROpCgfCL…zFXKf82zGODbRgPYNex7wH8okYB4LUyfQqxyNGjJ9A4lIb3Ak | 注销回调-oidc? http://localhost:5000/signout-callback-oidc?state=CfDJ8DwhaUXmuCROpCgfCLIYTwyHz6Z_WecMr8WjPz6O6F48TU3RrqurGDWG2WoOY-Y52iZP5ykUZFDFVFqOL4j8yiARGAVHDLii8h4JD6zFXKf82zGODbRgPYNex7wH 8okYB4LUyfQqxyNGjJ9A4lIb3Ak | 302 | 302 xhr / 重定向 |退出 | |获取 | http://localhost:5000/| 204 | 204飞行前 |飞行前 | |获取 | http://localhost:5000/| 400 | xhr |注销回调 oidc | |获取 | http://localhost:5000/GetXsrfToken | http://localhost:5000/GetXsrfToken | 200 | 200 xhr |用户配置文件.component.ts:42 |
什么可能导致它不断重定向到注销?
我更新了 Logout() 方法,它不再有无限循环。我需要返回一个重定向。它仍然没有重定向到身份验证服务器,但我为此提出了一个新问题。
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Logout()
{
await _signInManager.SignOutAsync();
SignOut(authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
return RedirectToAction(nameof(HomeController.Index), "Home");
}