Reputation: 819
I am trying to attach an angular application to a .NET core API utilizing the JWT token. At this point i have the local angular app authenticating with Cognito and getting the user account.
I've followed this to get the token attached to the request. https://medium.com/@umashankar.itn/aws-cognito-hosted-ui-with-angular-and-asp-net-core-5ddf351680a5
Amplify.Configure({
Auth: {
region: 'us-west-2',
userPoolId: 'us-west-MY POOL',
userPoolWebClientId: 'MY APP CLIENT ID'
}
}
});
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (request.url.indexOf(environment.api.baseUrl) == 0) {
return this.getToken().pipe(mergeMap(token => {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(request);
}));
}
return next.handle(request);
}
}
getToken() {
return from(
new Promise((resolve, reject) => {
Auth.currentSession()
.then((session) => {
if (!session.isValid()) {
resolve(null);
} else {
resolve(session.getIdToken().getJwtToken());
}
})
.catch(err => {
return resolve(null)
});
})
);
}
And i can confirm that it is adding the token to the request.
Interesting thing to note is that i'm using the session.getIdToken().getJwtToken()
but there also is session.getAccessToken().getJwtToken()
and they are different. I can't find anything telling me what the difference is, but i've tried both and they both have the same issue.
For the server side i've followed this answer to setup the .net core site and i can confirm that it is appropriately downloading the keys from /.well-known/jwks.json
. It however just keeps rejecting the request with authentication failure.
How to validate AWS Cognito JWT in .NET Core Web API using .AddJwtBearer()
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
{
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
// serialize the result
return JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
},
ValidateIssuer = true,
ValidIssuer = $"https://cognito-idp.us-west-2.amazonaws.com/us-west-MYID",
ValidateLifetime = true,
LifetimeValidator = (before, expires, token, param) => expires > DateTime.UtcNow,
ValidateAudience = true,
ValidAudience = "MY APP CLIENT ID"
};
});
app.UseAuthentication();
[HttpGet]
[Authorize]
public IEnumerable<Device> Get()
{
return 'my devices...';
}
The angular app is running at http://localhost:4200
and the .net core is running at https://localhost:44300
.
So the question i have is, am i missing some sort of setup in my cognito app client? What am i missing to get the .NET core app to take the JWT?
Upvotes: 1
Views: 1576
Reputation: 819
Turns out i actually did have everything correct as far as Cognito goes.
What i did have was this.
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Which is not the correct order for things to work... this is..
app.UseRouting();
app.UseAuthentication(); <-- Authentication before authorization
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
Upvotes: 4