我目前正在开发具有ASP.NET Core(2.1)API服务器/后端和Angular单页应用程序前端的应用程序。
对于用户身份验证,我使用的是ASP.NET Core Identity,以及AccountController
中提供的几种默认方法,用于登录,注销,注册,忘记密码等。我的Angular应用程序通过以下方式访问此API:执行这些操作。
Angular客户端文件直接从wwwroot
中托管在ASP.NET Core应用程序中。我在localhost:5000
下使用IIS Express托管(我也尝试过IIS,但无济于事)。
使用以下内容在ASP.NET Core的Startup
类中配置身份验证:
services.AddIdentity<ApplicationUser, IdentityRole>(config =>
{
config.SignIn.RequireConfirmedEmail = false;
config.Password.RequiredLength = 8;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
// Prevent API from redirecting to login or Access Denied screens (Angular handles these).
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
options.Events.OnRedirectToAccessDenied = context =>
{
context.Response.StatusCode = 403;
return Task.CompletedTask;
};
});
注册和忘记密码都可以顺利进行。调用该API并采取适当的措施。
登录出现起作用:该方法在Angular中调用:
@Injectable()
export class AuthService extends BaseService {
constructor(private httpClient: HttpClient) {
super(httpClient, `${config.SERVER_API_URL}/account`);
}
// Snip
login(login: Login): Observable<boolean> {
return this.httpClient.post<boolean>(`${this.actionUrl}/Login`, login)
.catch(this.handleError);
}
// Snip
}
ASP.NET Core API获取调用,登录用户并返回成功,以向Angular指示登录有效,并且他们应继续重定向用户:
namespace ApartmentBonds.Web.Api.Account
{
[Route("api/[controller]/[action]")]
public class AccountController : APIControllerBase
{
// Snip
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login([FromBody] LoginViewModel model, string returnUrl = null)
{
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe, false);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return Ok(true);
}
}
return Ok(false);
}
// Snip
}
}
会话cookie创建成功,并且可以在浏览器中看到它(在此屏幕截图中使用Firefox Quantum,但也已在IE,Firefox隐身模式下尝试过):
为了进行测试,我有另一个API方法,该方法仅返回调用用户是否已登录:
// Angular
isLoggedIn(): Observable<boolean> {
return this.httpClient.get<boolean>(`${this.actionUrl}/IsLoggedIn`)
.catch(this.handleError);
}
// ASP.NET Core API
[HttpGet]
[AllowAnonymous]
public IActionResult IsLoggedIn()
{
return Ok(_signInManager.IsSignedIn(User));
}
我在浏览器中进行此调用,,它返回false 。 (依赖于登录用户的网站的所有其他方面也显示用户尚未登录-此方法只是验证此问题的一种快速而肮脏的方法。)请注意,客户端正在正确发送身份cookie。连同请求:
由于这里唯一有问题的网站是localhost:5000
,所以我不确定为什么它不起作用。
我尝试过的事情
services.ConfigureApplicationCookie
之内
options.Events.Cookie.Domain
设置为localhost:5000
options.Events.Cookie.Path
设置为/api
localhost:8888
)托管网站有人有什么想法吗?
答案 0 :(得分:2)
为了使身份验证处理程序能够在请求上运行,您需要在中间件管道中使用app.UseAuthentication();
(在需要像MVC这样的中间件之前)。
答案 1 :(得分:0)
这是一个远景,但是令牌可能需要:在实际令牌前面带有空格的“承载者”。
答案 2 :(得分:0)
我认为在使用 AllowAnonymousAttribute 时,不应使用控制器的 User 属性。
尝试向某些授权端点发出请求。如果您未登录,则将获得状态码401(未授权)。