如何在 Blazor 服务器应用程序中使用信号器从 http 客户端获取令牌?
how to take token from http client with signalr in blazor server app?
我在我的 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);
}
请不要在 Server Blazor 应用程序中使用 HttpContext。它不可用。服务器端 Blazor 基于 WebSocket,而不是基于 HTTP 请求。只是不要那样做。
这里是我关于如何实施 OpenID Connect 和其他答案的链接,您可以在其中找到问题的答案。
查看这些:
注意:Jwt、OpenID Connect等相关答案比较多,大家自己去找
我在我的 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);
}
请不要在 Server Blazor 应用程序中使用 HttpContext。它不可用。服务器端 Blazor 基于 WebSocket,而不是基于 HTTP 请求。只是不要那样做。
这里是我关于如何实施 OpenID Connect 和其他答案的链接,您可以在其中找到问题的答案。
查看这些:
注意:Jwt、OpenID Connect等相关答案比较多,大家自己去找