Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "Theunis"

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:

  1. How can I get access to the claims from within the Application Service?
  2. I assume that there is a better way of achieving Cognito Authentication where, after I've validated the JWT token I probably perform some ABP magic to create an Abp Session such that all Application Services and Controllers can use the AbpSession just like they normally would, oblivious to the fact that the identity or the authentication actually came from AWS Cognito rather than ABP's built-in authentication mechanism. But I have no idea how to achieve this? How should AWS Cognito Authentication be implemented appropriately?

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);

Showing 1 to 1 of 1 entries