Menelaos Vergis
Menelaos Vergis

Reputation: 3955

Custom Authentication mechanism in ASP.Net Core

I need to authenticate my users using an external API from the login page. If the authentication from the external API succeed then I store at the session a AuthToken.

To check if the request is valid I have created the following Authorization Handler

public class ExtApiStoreRequirement : IAuthorizationRequirement
{
}
public class ExtApiAuthorizationHandler : AuthorizationHandler<ExtApiStoreRequirement>
{

    IHttpContextAccessor _accessor;
    public ExtApiAuthorizationHandler(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ExtApiStoreRequirement requirement)
    {
        var authState = GET_AUTH_FROM_SESSION(_accessor.HttpContext.Session);


        if (authState!=null)
        {
            _accessor.HttpContext.Response.Redirect("/Account/Login");
            //context.Fail(); <-- I removed that because it was responding an empty page
            context.Succeed(requirement);
        }
        else
            context.Succeed(requirement);

        return Task.CompletedTask;
    }
}

And I have registered this handler at my startup.cs

  services.AddAuthorization(options =>
        {
            options.AddPolicy("ExtApi",
                              policy => policy.Requirements.Add(new ExtApiStoreRequirement()));
        });

This approach is working but I don't feel confident because I have to call context.Succeed(requirement); for the redirection to work. If I call context.Fail() then no redirection takes place and all I see is an empty page.

Is there any security issue with this approach or I will be safe using it?

Upvotes: 1

Views: 2014

Answers (1)

adem caglin
adem caglin

Reputation: 24153

Your implementation is for authorization not authentication. I think instead of creating an authorization policy, writing custom authentication middleware would be right way for your case.

First see how to implement custom authentication Simple token based authentication/authorization in asp.net core for Mongodb datastore

To implement above way for your case HandleAuthenticateAsync should be something like below:

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    AuthenticateResult result = null;
    var principal = GetPrincipalFromSession();
    if(principal != null)
    {
         result = AuthenticateResult.Success(new AuthenticationTicket(principal,
                    new AuthenticationProperties(), Options.AuthenticationScheme));
    }
    else
    {
         result = AuthenticateResult.Skip();
    }
    return result;
}

Update based on comment:

protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext context)
{    
     Response.Redirect(Options.LoginPath);// you need to define LoginPath        
     return true;
}

Also you should store principal in session when user signs in.

Upvotes: 1

Related Questions