我在Blazor服务器应用程序中使用SignalR。我在startup.cs文件中添加了services.AddSignalR()
。那我就不能拿代币了。因为http上下文是null
。然后我从startup.cs文件中删除了services.AddSignalR()
。这是正常工作。然后我可以从http客户端获取令牌。如何解决?
谢谢。
Startup.cs文件:
services
.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = identityUrl.ToString();
options.SignedOutRedirectUri = callBackUrl.ToString();
options.ClientId = useLoadTest ? "mvctest" : "blazor";
options.ClientSecret = "secret";
options.ResponseType = useLoadTest ? "code id_token token" : "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.RequireHttpsMetadata = false;
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("post");
options.Scope.Add("family");
options.Scope.Add("webpostagg");
});
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSignalR();
services.AddHttpClient<IPostService, PostService>()
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>();
HttpClientAuthorizationDelegatingHandler.cs:
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccesor)
{
_httpContextAccesor = httpContextAccesor;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
string authorizationHeader;
if (_httpContextAccesor.HttpContext == null)
{
authorizationHeader = string.Empty;
}
else
{
authorizationHeader = _httpContextAccesor.HttpContext
.Request.Headers["Authorization"];
}
if (!string.IsNullOrEmpty(authorizationHeader))
{
request.Headers.Add("Authorization", new List<string>() { authorizationHeader });
}
var token = await GetToken();
if (token != null)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
return await base.SendAsync(request, cancellationToken);
}
public async Task<string> GetToken()
{
const string ACCESS_TOKEN = "access_token";
return await _httpContextAccesor.HttpContext
.GetTokenAsync(ACCESS_TOKEN);
}
请不要在服务器Blazor应用程序中使用HttpContext。它不可用。服务器端Blazor是基于WebSocket的,而不是基于HTTP请求的。只是不要那样做。
以下是我关于如何实现OpenIDConnect的回答的链接,以及其他链接,您可以在其中找到问题的答案。
请参阅以下内容:如何在没有微软身份的情况下对blazor服务器进行jwt身份验证?如何从blazor(服务器端(web应用程序获取访问令牌?如何通过IdentityServer4将OpenIdConnect添加到ASP.NET Core ServerSide Blazor web应用程序?如何从asp.net web api中的身份声明中获取JWT认证登录用户如何在服务器端Blazor中使用HttpContext对象来检索有关用户、用户代理的信息Blazor添加HttpClientHandler以在请求时将Jwt添加到HTTP标头
Blazor:当没有会话/JWT令牌时重定向到登录页面?
注意:还有更多与Jwt、OpenID Connect等相关的答案。你只需要查找它们