我正在开发使用API
和asp.net core2
投放的网络Angular
应用。详细的开发环境配置为here。
我正在尝试配置AntiForgeryToken
验证,但它仍然失败。我按照配置。 here,但我必须修改它,因为我的角度应用程序和asp.net服务器在两个不同的端口上运行,因为前端启动不会生成令牌。我通过在应用组件API
上调用/api/Account/ContactInitialization
路径(ngOnInit
)来启动后端,这允许我生成令牌。
配置如下所示,
IServiceCollection
服务:
services.AddAntiforgery(options =>
{
options.HeaderName = "X-CSRF-TOKEN";
options.SuppressXFrameOptionsHeader = false;
});
和IApplicationBuilder Configure
:
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/api/Account/ContactInitialization", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// We can send the request token as a JavaScript-readable cookie,
// and Angular will use it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
asp.net。生成两组密钥,
我使用[ValidateAntiForgeryToken]
修饰了我的方法,并在标头请求中包含了XSRF-TOKEN
Cookie内容。但在致电400 (Bad Request)
后我仍然收到API
回复!我在这里错过了什么?
控制器方法,
[Authorize]
[ValidateAntiForgeryToken]
[HttpPost]
public IEnumerable<string> AutherizeCookie()
{
return new string[] { "Hello", "Auth Cookie" };
}
我的详细标题请求如下所示,
答案 0 :(得分:4)
我假设你可能跟随documentation,但是掩盖了相关的位。到目前为止您所做的只适用于Angular,因为Angular的$http
实际上会根据X-XSRF-TOKEN
Cookie添加XSRF-TOKEN
标头。 (但是,请注意,即使这样,您也可以将标题设置为X-CSRF-TOKEN
,但这实际上不会在这里工作。它必须是X-XSRF-TOKEN
)。
但是,如果您不使用Angular,那么您自己负责在AJAX请求中设置标头,这可能是您忽略的。在这种情况下,您实际上并不需要更改任何防伪令牌配置(标题名称,设置Cookie等)。您只需将标头提供为RequestVerificationToken
即可。例如,使用jQuery:
$.ajax({
...
headers:
{
"RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},
...
});
这将适用于JavaScript。如果你需要在外部JS中执行此操作,那么您需要设置cookie,以便您可以从cookie中获取值。除此之外,适用相同的方法。
如果您只想更改标题名称,则可以这样做;您只需将此处的RequestVerificationHeader
部分更改为相同的值。
答案 1 :(得分:1)
您需要发出XHR请求withCredentials = true,这将使浏览器设置cookie,否则您将获得400错误请求,因为cookie不存在且X-XSRF-TOKEN未设置或设置为空字符串
答案 2 :(得分:0)
谢谢,@ Chris_Pratt指出我遇到的标题问题。但是,为了说清楚,我还有其他问题需要解决。
我的CORS
配置错误,我的工作代码如下,
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.WithOrigins("https://www.artngcore.com:4200") //Note: The URL must be specified without a trailing slash (/).
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
services.AddAntiforgery(options =>
{
options.HeaderName = "X-XSRF-TOKEN";
options.SuppressXFrameOptionsHeader = false;
});
和middleware
配置是,
app.Use(next => context =>
{
string path = context.Request.Path.Value;
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false,
Secure = true // set false if not using SSL });
return next(context);
});
并在控制器中,
[Route("/api/[controller]/[action]")]
[EnableCors("CorsPolicy")]
public class AccountController : ArtCoreSecuredController ....
这里的诀窍是令牌必须在身份验证后刷新。在身份验证(登录)之后调用API将执行此操作。 不要忘记在您的请求中添加以下标题,
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.cookieService.get('ArtCoreToken')}`,
'X-XSRF-TOKEN': `${this.cookieService.get('XSRF-TOKEN')}`
});
即
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> RefreshToken()
{
await Task.Delay(1);
return StatusCode(200);
}
这对我有用。希望它有所帮助。