我被要求在一台机器上托管一个 IdentityServer
https://localhost:5001
并拥有用于使用 React 登录的自定义页面。我可以单击登录按钮,它会将我重定向到已设置 ReturnUrl 的登录页面,一旦我通过 axios 发送请求,它就会到达登录控制器。
现在的问题是,一旦它返回带有redirect_uri 的Ok() 响应,就不会创建任何cookie。有一个 cookie,但它没有 access_token、refresh_token、id_token 或用户信息。
[HttpPost("login")]
public async Task<IActionResult> Login(string username, string password, string returnUrl)
{
// check if we are in the context of an authorization request
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
if (context == null)
{
return Redirect("~/");
}
var user = await _userManager.FindByNameAsync(username);
if(await _userManager.CheckPasswordAsync(user, password))
{
var claims = new List<Claim>
{
new("Sub", user.Id),
new(ClaimTypes.Name, user.Email),
new("FullName", user.Name),
new(ClaimTypes.Role, "User")
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
AllowRefresh = true,
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(20),
IsPersistent = true,
IssuedUtc = DateTimeOffset.UtcNow,
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
return Ok(context.RedirectUri);
}
return BadRequest("Something went wrong");
}
和 HostingExtensions.cs
public static WebApplication ConfigureServices(this WebApplicationBuilder builder)
{
var migrationsAssembly = typeof(Program).Assembly.GetName().Name;
var connectionString = builder.Configuration.GetConnectionString("EFConn");
builder.Services.AddControllers();
builder.Services.AddDbContext<DbContext>(opt =>
{
opt.UseNpgsql(connectionString, opt => opt.MigrationsAssembly(migrationsAssembly));
});
builder.Services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<DbContext>()
.AddDefaultTokenProviders();
builder.Services.AddIdentityServer(options =>
{
// I had to override the IReturnUrlParser class
options.UserInteraction.LoginUrl = "https://localhost:5003/login.html";
options.UserInteraction.ErrorUrl = "http://localhost:5001/error.html";
options.UserInteraction.LogoutUrl = "http://localhost:8082/logout.html";
options.EmitStaticAudienceClaim = true;
options.Events.RaiseErrorEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseSuccessEvents = true;
})
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseNpgsql(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddAspNetIdentity<User>();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Forbidden/";
});
var cors = new DefaultCorsPolicyService(new LoggerFactory().CreateLogger<DefaultCorsPolicyService>()){ AllowAll = true };
builder.Services.AddSingleton<ICorsPolicyService>(cors);
builder.Services.AddTransient<IReturnUrlParser, ReturnUrlParser>();
builder.Services.AddCors(options =>
{
// this defines a CORS policy called "default"
options.AddPolicy("default", policy =>
{
policy
.WithMethods("GET", "POST", "PATCH", "DELETE", "OPTIONS")
.AllowAnyHeader()
.WithOrigins("https://localhost:5003");
});
});
return builder.Build();
}
public static WebApplication ConfigurePipeline(this WebApplication app)
{
app.UseSerilogRequestLogging();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
InitializeDatabase(app);
app.UseCors("default");
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.MapControllers();
return app;
}
我在浏览器上得到的唯一东西就是这个 aspnet cookie:
我已经搜索了很长时间,但仍然找不到任何人尝试过这样做。
您的 cookie 不会有访问令牌或 ID 令牌。用户登录后,声明将被添加并保存在 cookie 中。在下一个请求中,如果设置了声明并且用户经过身份验证,那么您将获得访问令牌/ID 令牌。如果您想更改 cookie 的名称,那么您可以遵循“AddIdentityServer”方法中的属性
options.Authentication.CookieSlidingExpiration = true;
options.Authentication.CookieLifetime = TimeSpan.FromMinutes(45);
options.Authentication.CheckSessionCookieName = "mycookiename";