Search code examples
oauth-2.0facebook-authenticationthinktecture-ident-server

Thinktecture Identity server v3 - Facebook Assertion Flow


Is there a possibility to configure OAuth2 AssertionFlow with Facebook in Thinktecture Identity Server v3?

There was a post on leastprivilege.com about implementing AssertionFlow for Microsoft OAuth and AuthorizationServer but I need to integrate with Facebook and, furthermore, AuthorizationServer is marked as deprecated and it's not maintained anymore.


Solution

  • In response to @NathanAldenSr's comment, I publish some code of my working solution.

    Server side - custom validator:

        public class FacebookCustomGrantValidator: ICustomGrantValidator
        {
            private readonly IUserService userService;
            private const string _FACEBOOK_PROVIDER_NAME = "facebook";
            // ...
    
            async Task<CustomGrantValidationResult>  ICustomGrantValidator.ValidateAsync(ValidatedTokenRequest request)
            {
                // check assetion type (you can have more than one in your app)
                if (request.GrantType != "assertion_fb")
                    return await Task.FromResult<CustomGrantValidationResult>(null);
    
                // I assume that fb access token has been sent as a response form value (with 'assertion' key)
                var fbAccessToken = request.Raw.Get("assertion");
                if (string.IsNullOrWhiteSpace(assertion))
                    return await Task.FromResult<CustomGrantValidationResult>(new CustomGrantValidationResult
                    {
                        ErrorMessage = "Missing assertion."
                    });
    
                AuthenticateResult authebticationResult = null;
    
                // if fb access token is invalid you won't be able to create Facebook client 
                var client = new Facebook.FacebookClient(fbAccessToken);
                dynamic response = client.Get("me", new { fields = "email, first_name, last_name" });
    
                // create idsrv identity for the user
                authebticationResult = await userService.AuthenticateExternalAsync(new ExternalIdentity()
                {
                    Provider = _FACEBOOK_PROVIDER_NAME,
                    ProviderId = response.id,
                    Claims = new List<Claim>
                    {
                        new Claim("Email", response.email),
                        new Claim("FirstName", response.first_name),
                        new Claim("LastName", response.last_name)
                        // ... and so on...
                    }
                },
                new SignInMessage());
    
                return new CustomGrantValidationResult
                {
                    Principal = authebticationResult.User
                };
            }
        }
    

    You can easily test it with OAuth2Client that is also provided by Thinktecture (in Thinktexture.IdentityModel Client Library nuget package).

    string fbAccessToken = "facebook_access_token_you_aquired_while_logging_in";
    string assertionType = "assertion_fb";
    
    var client = new OAuth2Client(
                       new Uri("your_auth_server_url"),
                       "idsrv_client_id",
                       "idsrv_client_secret");
    
    string idsrvAccessToken = client.RequestAssertionAsync(assetionType, fbAccessToken,).Result;