【发布时间】:2021-05-08 07:30:44
【问题描述】:
我有一个调用身份验证服务器的 Blazor 服务器端应用程序。我拥有身份验证服务器(也是一个 ASP.NET Core WebApp),它基于 OpenIdDict。我已经用 oidcdebugger.com 测试过,可以成功生成授权码。
授权服务器重定向回应用程序,以便应用程序完成授权码流程,用户可以访问应用程序。
我做的第一件事是在MainLayout.razor:
@inherits LayoutComponentBase
<AuthorizeView>
<NotAuthorized>
<GetAuthorizationCode/>
</NotAuthorized>
<Authorized>
<Header/>
<NavMenu/>
</Authorized>
</AuthorizeView>
@code {
}
GetAuthorizationCode 是一个简单的组件,它是:
public class GetAuthorizationCode: ComponentBase
{
[Inject]
protected IAuthService AuthService { get; set; }
protected override void OnInitialized()
{
base.OnInitialized();
AuthService.GetAuthorizationCode();
}
}
服务准备发送到认证服务器的请求:
public void GetAuthorizationCode()
{
var url = "urltoauthserver";
var parameters = new Dictionary<string, string>()
{
{ "client_id", "hereclientid" },
{ "redirect_uri", "hereredirecturi" },
{ "scope", "openid email profile" },
{ "response_type", "code" },
{ "response_mode", "form_post" },
{ "state", Guid.NewGuid().ToString() },
{ "nonce", "herenonce" }
};
url = QueryHelpers.AddQueryString(url, parameters);
navigationManager.NavigateTo(url);
}
重定向 uri 是 Blazor 应用程序本身中的一个 api 控制器(不是另一个外部 api)。我需要使用 api 控制器,因为重定向 uri 是一个 POST,看起来像这样:
[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class LoginController : ControllerBase
{
[HttpPost]
public IActionResult Callback([FromForm] string code, [FromForm] string state)
{
return Ok($"Login callback. Access token: {code}");
}
}
流程应该是一旦身份验证服务器对用户进行身份验证并将授权代码发送回重定向 uri,上述操作应该创建一个带有授权代码的请求以发送到身份验证服务器并接收访问令牌。
在startup.cs我还配置了OpenIdConnect如下:
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ClientId = "hereclientid";
options.ClientSecret = "hereclientsecret";
options.RequireHttpsMetadata = false;
options.GetClaimsFromUserInfoEndpoint = true;
options.SaveTokens = true;
options.ResponseType = OpenIdConnectResponseType.Code;
options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;
options.Authority = "authserver";
options.Scope.Add("email");
options.Scope.Add("profile");
options.SecurityTokenValidator = new JwtSecurityTokenHandler
{
InboundClaimTypeMap = new Dictionary<string, string>()
};
options.TokenValidationParameters.NameClaimType = "name";
});
问题是永远无法到达该操作,因为在重定向期间,GetAuthorizationCode 被一遍又一遍地调用。
编辑 如果重定向是 GET,则会发生无限循环。如果重定向是 POST,我会收到 400 Bad Request,这是日志:
2021-02-04 16:56:19.628 +01:00 [INF] 请求开始 HTTP/2 POST https://localhost:44379/api/Login/Callback application/x-www-form-urlencoded 91 2021-02-04 16:56:19.628 +01:00 [INF] CORS 策略执行成功。 2021-02-04 16:56:19.629 +01:00 [INF] 执行端点'/_Host' 2021-02-04 16:56:19.629 +01:00 [INF] 路由与 {page = "/_Host", action = "", controller = ""} 匹配。执行页面/_Host 2021-02-04 16:56:19.639 +01:00 [INF] 防伪令牌验证失败。表单字段“__RequestVerificationToken”或标头值“RequestVerificationToken”中均未提供所需的防伪请求令牌。 Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException:未在表单字段“__RequestVerificationToken”或标头值“RequestVerificationToken”中提供所需的防伪请求令牌。 在 Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.ValidateRequestAsync(HttpContext httpContext) 在 Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.ValidateAntiforgeryTokenAuthorizationFilter.OnAuthorizationAsync(AuthorizationFilterContext 上下文) 2021-02-04 16:56:19.671 +01:00 [INF] 过滤器“Microsoft.AspNetCore.Mvc.ViewFeatures.Filters.AutoValidateAntiforgeryTokenAuthorizationFilter”的请求授权失败。 2021-02-04 16:56:19.674 +01:00 [INF] 执行 HttpStatusCodeResult,设置 HTTP 状态码 400 2021-02-04 16:56:19.674 +01:00 [INF] 在 45.2108 毫秒内执行页面 /_Host 2021-02-04 16:56:19.674 +01:00 [INF] 执行端点'/_Host' 2021-02-04 16:56:19.675 +01:00 [INF] 请求完成 HTTP/2 POST https://localhost:44379/api/Login/Callback application/x-www-form-urlencoded 91 - 400 - - 47.2169ms
我为 POST 操作添加了[IgnoreAntiForgeryToken],但它不起作用
【问题讨论】:
标签: asp.net-core blazor blazor-server-side