We are using ASP.NET Zero and we want to use AWS Cognito as Authentication Provider. We are using Cognito to authenticate on Mobile Apps and we also aim to use Cognito to authenticate on the Angular ASP.Net Zero Web Application. Thus, we want to authenticate against a Cognito JWT Access Token in our Application Services as well as our Controllers. I have added JWT Token validation in the Web.Host project and I have decorated the Application Service class with the [Authorize] attribute. When I make a call to the API with a valid JWT token from Cognito I am able to access the service whereas if I have an invalid token I get a 401 Unauthorized error. So the authorization and token validation works nicely as expected. However, I am now trying to identify the user within the Application Service and I am unable to do so. If I set a breakpoint inside the method in the Application Service I can see that the PrincipalAccessor contains the claims from the JWT token. The Principal Accessor isn't accessible from the Application Service though so I don't have a means of reading it. When I try to read a user identifier I also get null values and if I use GetCurrentUser() I get an exception that Session.UserId is null.
I have two questions:
This is my code in my Application Service:
public class HelloWorldAppService : ITSAppServiceBase, IHelloWorldAppService
{
[Authorize]
public HelloWorldDto GetAll()
{
var temp = this.AbpSession.ToString();
var id = this.AbpSession.ToUserIdentifier(); //id is null
//var u = this.GetCurrentUser(); //method throws an exception: Session.UserId is null! Probably, user is not logged in.
return new HelloWorldDto() { Message = "Hello world!"};
}
}
This is the content of AbpSession when I set a breakpoint in the method in the Application Service:
This is the extension we have added in our Web.Host project to validate the JWT token:
` public static IServiceCollection AddAwsCognitoAuthentication(this IServiceCollection services, AppSettings appSettings) {
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.ClaimsIssuer = CognitoIssuer;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) => {
// get JsonWebKeySet from AWS
var json = new WebClient().DownloadString(CognitoIssuer + "/.well-known/jwks.json");
// serialize the result
var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;
// cast the result to be the type expected by IssuerSigningKeyResolver
return keys;
},
ValidateIssuer = true,
ValidIssuer = CognitoIssuer,
ValidateAudience = false,
};
options.Events = new JwtBearerEvents() {
//Code omitted for brevity
};
});
return services;
}`
and we are calling this extension in Startup.cs:
services.AddAwsCognitoAuthentication(_appSettings);