Neville Nazerane
Neville Nazerane

Reputation: 7049

Facebook Authentication access principal

I have a .net core web API with a custom authentication scheme. Now I am trying to set up a facebook login and access the claims principle created.

The following code works fine with cookies:

services.AddAuthentication()
    .AddCookie()
    .AddFacebook(config => {
        // appid and secret set up here
        config.CallbackPath = "/externalLogin";
        config.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    });

With this code, once I use [Authorize(AuthenticationSchemes = FacebookDefaults.AuthenticationScheme)] on an action, it logs in with cookies and I can access the principal via the User.Identity property.

I am trying to get this principal before it is set into the cookie via the sign in scheme. I have set tried setting up a custom scheme for this:

services.AddAuthentication()
    .AddScheme<ExternalOptions, ExternalLogin>(ExternalLogin.SchemeName, config => { })
    .AddFacebook(config => {
        // appid and secret set up here
        config.CallbackPath = "/externalLogin";
        config.SignInScheme = ExternalLogin.SchemeName;

    });

And I have defined my empty classes for scheme yet:

public class ExternalOptions : AuthenticationSchemeOptions { }

public class ExternalLogin : AuthenticationHandler<ExternalOptions>
{

    public const string SchemeName = "External";

    public ExternalLogin(IOptionsMonitor<ExternalOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) 
        : base(options, logger, encoder, clock)
    {

    }
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        // need to access the principal here
        return AuthenticateResult.Fail("Failed!");
    }
}

I try using the debugger on return AuthenticateResult.Fail("Failed!") but I don't find property that contains the principal info.

Note: I need to make sure that there are no cookies used to maintain statelessness and in case a client has their cookies blocked (i guess would create an issue). Either ways it isn't considered good to enable cookies on a Web API. Secondly the aim is to set up an external auth that can be later commonly re-used across future external logins as well (such as google and ms).

Upvotes: 0

Views: 86

Answers (1)

M&#233;toule
M&#233;toule

Reputation: 14502

It's possible to access the ClaimsPrincipal at various points of the authentification process via the scheme options.Events (each scheme defines its own events).

Here, you can use the cookies events. For example:

services
    .AddAuthentication()
    .AddCookie(options => 
    {
        // there are various events, be sure to use 
        // the appropriate one for your use case
        options.Events.OnValidatePrincipal = (context) =>
        {
            var principal = context.Principal;

            // reject the principal?
            if (principal.Identity.Name != "MyUser")
                context.RejectPrincipal();

            // each event expect a Task
            return Task.CompletedTask;
        };
    )
    .AddFacebook(config => {
        // appid and secret set up here
        config.CallbackPath = "/externalLogin";
        config.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    });

Upvotes: 1

Related Questions