Jos*_*ing 2 api asp.net-core blazor
我使用 blazor 作为前端,api 已完成 JWT 配置。前端可以创建用户帐户并登录API,但现在我的前端httpclient没有设置JWT令牌,所以如果我在Api控制器中设置[授权],前端将无法访问它。
api程序代码如下
builder.Services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<DBContext>();//add user model,role model and connect toDbcontext
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuer = true,
ValidIssuer = builder.Configuration["Authentication:Issuer"],
ValidateAudience = true,
ValidAudience = builder.Configuration["Authentication:Audience"],
ValidateLifetime = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]))
};
});
Run Code Online (Sandbox Code Playgroud)
控制器代码如下
[HttpGet("all")]
[HttpHead]
//[Authorize(AuthenticationSchemes = "Bearer")]
[Authorize]
public async Task<ActionResult<IEnumerable<Quiz>>> GetQuizzesDetailsAsync() {
var quizzes= await _quizzesRepository.GetQuizzesDetailsAsync( );
var quizDtos=_mapper.Map<IEnumerable<QuizOverviewDto>>(quizzes);
return Ok(quizDtos);
}
Run Code Online (Sandbox Code Playgroud)
前端 Blazor 程序代码如下
builder.Services.AddHttpClient<IQuizService, QuizService>(
client => client.BaseAddress = new Uri("https://localhost:7172"))
.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
Run Code Online (Sandbox Code Playgroud)
和“CustomAuthorizationMessageHandler”代码如下。
public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler {
public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
NavigationManager navigationManager)
: base(provider, navigationManager) {
ConfigureHandler(
authorizedUrls: new[] { "https://localhost:7172" });
}
}
Run Code Online (Sandbox Code Playgroud)
}
访问服务如下
public async Task<IEnumerable<QuizOverviewDto>> GetQuizzesDetailsAsync() {
return await JsonSerializer.DeserializeAsync<IEnumerable<QuizOverviewDto>>(
await _httpClient.GetStreamAsync("api/quizzes/all"),
new JsonSerializerOptions {
PropertyNameCaseInsensitive = true
});
}
Run Code Online (Sandbox Code Playgroud)
现在当我调用 GetQuizzesDetailsAsync() 这个服务时,它给我一个错误。
Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:尝试激活“PerfectPoliciesFE.CustomAuthorizationMessageHandler”时无法解析类型“Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider”的服务。System.InvalidOperationException:尝试激活“PerfectPoliciesFE.CustomAuthorizationMessageHandler”时无法解析类型“Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider”的服务。在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(类型实现类型,CallSiteChain callSiteChain,ParameterInfo []参数,布尔型 throwIfCallSiteNotFound) 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache 生命周期,类型 serviceType,类型实现类型,CallSiteChain调用站点链)
我的代码有什么问题?我想我只将登录用户的令牌附加到http请求,并且它可以成功访问,有什么简单的方法可以做到这一点吗?
如果您使用 Blazor WebAssembly,则需要IAccessTokenProvider从Microsoft.AspNetCore.Components.WebAssembly.Authentication服务内的命名空间注入 并从那里获取令牌。获得令牌后,您可以将令牌值传递到 httpclient 的 Authorization 标头。
private readonly IAccessTokenProvider _tokenProvider;
private readonly HttpClient _httpClient;
public class QuizService(IAccessTokenProvider tokenProvider, HttpClient httpClient)
{
_tokenProvider = tokenProvider;
_httpClient = httpClient;
}
private async Task RequestAuthToken()
{
var requestToken = await _tokenProvider.RequestAccessToken();
requestToken.TryGetToken(out var token);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Value);
}
public async Task<IEnumerable<QuizOverviewDto>> GetQuizzesDetailsAsync()
{
await RequestAuthToken();
return await JsonSerializer.DeserializeAsync<IEnumerable<QuizOverviewDto>>(
await _httpClient.GetStreamAsync("api/quizzes/all"),
new JsonSerializerOptions {
PropertyNameCaseInsensitive = true
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3034 次 |
| 最近记录: |