Reputation: 310
Having upgraded from 3.1 to 5.0, I cannot seem to get past this HttpRequestException
error when trying to fetch data from protected api controllers (those not marked [Authorize]
are fine).
Although the client app tells me I am authenticated (I have 'hello, [email protected]' up top right for example), I can't seem to be get authenticated with the server. User.Identity just looks like this for example:
I have a few typed HttpClients, the authenticating one looking like so
public class ApplicationClient
{
private readonly HttpClient _httpClient;
public ApplicationClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Applicant> GetApplicant() => await _httpClient.GetFromJsonAsync<Applicant>("applicant");
}}
With ApplicationClient
being register in Programme.cs
on client
side as:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddHttpClient<ApplicationClient>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("Jcc.ServerAPI"));
builder.Services.AddScoped<ApplicationState>();
builder.Services.AddBlazoredModal();
builder.Services.AddApiAuthorization();
await builder.Build().RunAsync();
}
And finally a controller,
[Route("[controller]")]
[ApiController]
[Authorize]
public class MyController
{
public MyController(...) : base(...)
{
...
}
[HttpGet]
public async Task<ActionResult<Applicant>> GetCurrentApplicant()
{
...
}
In Startup.cs
on Server
app (having chopped and changed and tried about every combination of the below plus others) the pertinent bits of ConfigureServices()
are:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<JccContext>(options =>
options.UseNpgsql(
Configuration.GetConnectionString("DbContext")));
services.AddDefaultIdentity<ApplicationUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<DbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, DbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
services.Configure<IdentityOptions>(options =>
options.ClaimsIdentity.UserIdClaimType = ClaimTypes.NameIdentifier);
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto |
ForwardedHeaders.XForwardedHost;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
while Configure()
goes:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
app.UseHttpsRedirection();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles();
app.UseBlazorFrameworkFiles();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapDefaultControllerRoute();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
I just don't what's changed since it worked previously. Identity Server seems to generate the token fine:
but I keep seeing this:
It would be nice to not have to revert back to 3.1 :)
I did try
services.AddIdentityServer(opt =>
opt.IssuerUri = "https://localhost:5001"
)
As per a post a few years back but no dice and I think it was a different issue.
Upvotes: 1
Views: 483
Reputation: 19921
If you regenerate the signing keys, then the keys in tokens already issued will be invalidated. For production you need to make sure the signing keys is persisted.
you can look at the kid claim in the JWT header of your tokens. It must be found in the /.well-known/openid-configuration/jwks.
Be aware that API's and clients cache the downloaded keys for 24 hours by default.
In production you need to use this method to add the signing key that you want to sign your tokens with
AddSigningCredential
See the documentation here
In production you should not use this method AddDeveloperSigningCredential.
Upvotes: 1