Search code examples
c#claims-based-identitythinktecture-ident-server

Thinktecture Identity Server v3 How to keep Claims from external providers?


I'm trying to follow the simple guide mvcGettingStarted. Now, I've implemented both GoogleAuthentication and FacebookAuthentication providers, and everything is working as expected, I actually can log-in, and if I sign in with my identity server I also got the Role claims per user. I was wondering, what if I want to keep all the claims given from the external providers? Simple example. This is how my Facebook provider setup looks like:

var facebookOptions = new FacebookAuthenticationOptions() {
            AuthenticationType = "Facebook",
            Caption = "Sign in with Facebook",
            AppId = "*****",
            AppSecret = "****",
            SignInAsAuthenticationType = signInAsType,
            Provider = new FacebookAuthenticationProvider() {
                OnAuthenticated = (context) => {

                    foreach (var x in context.User) {
                        context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString()));
                    }

                    return Task.FromResult(context);
                }
            },
        };

        facebookOptions.Scope.Add("email");
        facebookOptions.Scope.Add("public_profile");
        facebookOptions.Scope.Add("user_friends");

        app.UseFacebookAuthentication(facebookOptions);

In the for each loop I'm trying to store all the Facebook claims in the Identity, but when I get back in the SecurityTokenValidated callback, my Identity hasn't them.

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() {
            Authority = "https://localhost:44302/identity/",
            ClientId = "my_client",
            Scope = "openid profile roles email",
            RedirectUri = "https://localhost:44302/",
            ResponseType = "id_token token",
            SignInAsAuthenticationType = "Cookies",
            UseTokenLifetime = false,
            Notifications = new OpenIdConnectAuthenticationNotifications() {

                SecurityTokenValidated = async context => {
                    //let's clean up this identity

                    //context.AuthenticationTicket.Identity doesn't have the claims added in the facebook callback
                    var nid = new ClaimsIdentity(
                        context.AuthenticationTicket.Identity.AuthenticationType,
                        Constants.ClaimTypes.GivenName,
                        Constants.ClaimTypes.Role);
                    ........

Is it because I'm manipulating two different Identities? Is there a right way to achieve what I am trying to do? Thank you.


Solution

  • You would do this in your custom user service implementation. The default one makes the claims from the external provider available. Docs on a custom user service: https://identityserver.github.io/Documentation/docsv2/advanced/userService.html