{"action":"created","issue":{"url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/821","labels_url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/821/labels{/name}","comments_url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/821/comments","events_url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/821/events","html_url":"https://github.com/IdentityServer/Thinktecture.IdentityServer3/issues/821","id":55477066,"number":821,"title":"Reach claims from external provider in OpenIdConnectAuthenticationNotifications","user":{"login":"DMDc0de","id":7113516,"avatar_url":"https://avatars.githubusercontent.com/u/7113516?v=3","gravatar_id":"","url":"https://api.github.com/users/DMDc0de","html_url":"https://github.com/DMDc0de","followers_url":"https://api.github.com/users/DMDc0de/followers","following_url":"https://api.github.com/users/DMDc0de/following{/other_user}","gists_url":"https://api.github.com/users/DMDc0de/gists{/gist_id}","starred_url":"https://api.github.com/users/DMDc0de/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DMDc0de/subscriptions","organizations_url":"https://api.github.com/users/DMDc0de/orgs","repos_url":"https://api.github.com/users/DMDc0de/repos","events_url":"https://api.github.com/users/DMDc0de/events{/privacy}","received_events_url":"https://api.github.com/users/DMDc0de/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-01-26T12:30:19Z","updated_at":"2015-01-26T16:08:12Z","closed_at":null,"body":"Hello, I'm trying to follow your simple guide [mvcGettingStarted](http://identityserver.github.io/Documentation/docs/overview/mvcGettingStarted.html).\r\nNow, 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.\r\nI was wondering, what if I want to keep all the claims given from the external providers?\r\nSimple example.\r\nThis is how my facebook provider setup looks like:\r\n```C#\r\nvar facebookOptions = new FacebookAuthenticationOptions() {\r\n                AuthenticationType = \"Facebook\",\r\n                Caption = \"Sign in with Facebook\",\r\n                AppId = \"*****\",\r\n                AppSecret = \"****\",\r\n                SignInAsAuthenticationType = signInAsType,\r\n                Provider = new FacebookAuthenticationProvider() {\r\n                    OnAuthenticated = (context) => {\r\n\r\n                        foreach (var x in context.User) {\r\n                            context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString()));\r\n                        }\r\n\r\n                        return Task.FromResult(context);\r\n                    }\r\n                },\r\n            };\r\n\r\n            facebookOptions.Scope.Add(\"email\");\r\n            facebookOptions.Scope.Add(\"public_profile\");\r\n            facebookOptions.Scope.Add(\"user_friends\");\r\n\r\n            app.UseFacebookAuthentication(facebookOptions);\r\n```\r\n\r\nIn the foreach loop I', trying to store all the facebook claims in the Identity, but when I get back in the SecurityTokenValidated callback, my Identity hasn't them.\r\n```C#\r\napp.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() {\r\n                Authority = \"https://localhost:44302/identity/\",\r\n                ClientId = \"my_client\",\r\n                Scope = \"openid profile roles email\",\r\n                RedirectUri = \"https://localhost:44302/\",\r\n                ResponseType = \"id_token token\",\r\n                SignInAsAuthenticationType = \"Cookies\",\r\n                UseTokenLifetime = false,\r\n                Notifications = new OpenIdConnectAuthenticationNotifications() {\r\n\r\n                    SecurityTokenValidated = async context => {\r\n                        //let's clean up this identity\r\n\r\n                        //context.AuthenticationTicket.Identity doesn't have the claims added in the facebook callback\r\n                        var nid = new ClaimsIdentity(\r\n                            context.AuthenticationTicket.Identity.AuthenticationType,\r\n                            Constants.ClaimTypes.GivenName,\r\n                            Constants.ClaimTypes.Role);\r\n                        ........\r\n```\r\nIs it because I'm manipulating two different Identites? \r\nIs there a right way to achieve what I am trying to do?\r\nThank you. \r\n\r\n\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/comments/71485157","html_url":"https://github.com/IdentityServer/Thinktecture.IdentityServer3/issues/821#issuecomment-71485157","issue_url":"https://api.github.com/repos/IdentityServer/Thinktecture.IdentityServer3/issues/821","id":71485157,"user":{"login":"DMDc0de","id":7113516,"avatar_url":"https://avatars.githubusercontent.com/u/7113516?v=3","gravatar_id":"","url":"https://api.github.com/users/DMDc0de","html_url":"https://github.com/DMDc0de","followers_url":"https://api.github.com/users/DMDc0de/followers","following_url":"https://api.github.com/users/DMDc0de/following{/other_user}","gists_url":"https://api.github.com/users/DMDc0de/gists{/gist_id}","starred_url":"https://api.github.com/users/DMDc0de/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DMDc0de/subscriptions","organizations_url":"https://api.github.com/users/DMDc0de/orgs","repos_url":"https://api.github.com/users/DMDc0de/repos","events_url":"https://api.github.com/users/DMDc0de/events{/privacy}","received_events_url":"https://api.github.com/users/DMDc0de/received_events","type":"User","site_admin":false},"created_at":"2015-01-26T16:08:12Z","updated_at":"2015-01-26T16:08:12Z","body":"Right now it's all in the Startup class of the project that holds a self hosted idsrv. This is the full class\r\n```\r\npublic class Startup {\r\n\r\n        public void Configuration(IAppBuilder app) {\r\n            AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject;\r\n            JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();\r\n\r\n//            app.SetDefaultSignInAsAuthenticationType(OpenIdConnectAuthenticationDefaults.AuthenticationType);\r\n            var factory = InMemoryFactory.Create(\r\n                users: Users.Get(),\r\n                clients: Clients.Get(),\r\n                scopes: Scopes.Get());\r\n//            factory.ClaimsProvider = new Registration<IClaimsProvider>(resolver => new CustomClaimsProvider());\r\n\r\n            app.Map(\"/identity\", idsrvApp => idsrvApp.UseIdentityServer(new IdentityServerOptions {\r\n                SiteName = \"IPPS Web Public IdentityServer\",\r\n                SigningCertificate = LoadCertificate(),\r\n                Factory = factory,\r\n                AuthenticationOptions = new Thinktecture.IdentityServer.Core.Configuration.AuthenticationOptions() {\r\n                    IdentityProviders = ConfigureIdentityProviders\r\n                }\r\n            }));\r\n\r\n\r\n            app.UseCookieAuthentication(new CookieAuthenticationOptions() {\r\n                AuthenticationType = \"Cookies\"\r\n            });\r\n\r\n            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() {\r\n                Authority = \"https://localhost:44302/identity/\",\r\n                ClientId = \"ipps.web.public\",\r\n                Scope = \"openid profile roles email publicAPI\",\r\n                RedirectUri = \"https://localhost:44302/\",\r\n                ResponseType = \"id_token token\",\r\n                SignInAsAuthenticationType = \"Cookies\",\r\n                UseTokenLifetime = false,\r\n                Notifications = new OpenIdConnectAuthenticationNotifications() {\r\n\r\n                    SecurityTokenValidated = async context => {\r\n                        //let's clean up this identity\r\n\r\n                        //context.AuthenticationTicket.Identity doesn't have the claims added in the facebook callback\r\n                        var nid = new ClaimsIdentity(\r\n                            context.AuthenticationTicket.Identity.AuthenticationType,\r\n                            Constants.ClaimTypes.GivenName,\r\n                            Constants.ClaimTypes.Role);\r\n                        \r\n\r\n                        // get userinfo data\r\n                        var userInfoClient = new Thinktecture.IdentityModel.Client.UserInfoClient(\r\n                            new Uri(context.Options.Authority + \"/connect/userinfo\"),\r\n                            context.ProtocolMessage.AccessToken);\r\n\r\n                        var userInfo = await userInfoClient.GetAsync();\r\n                        userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2)));\r\n\r\n                        // keep the id_token for logout\r\n                        nid.AddClaim(new Claim(\"id_token\", context.ProtocolMessage.IdToken));\r\n\r\n                        // add access token for IPPS API\r\n                        nid.AddClaim(new Claim(\"access_token\", context.ProtocolMessage.AccessToken));\r\n\r\n                        // keep track of access token expiration\r\n                        nid.AddClaim(new Claim(\"expires_at\", DateTimeOffset.Now.AddSeconds(int.Parse(context.ProtocolMessage.ExpiresIn)).ToString()));\r\n\r\n                        // add some other app specific claim\r\n//                        nid.AddClaim(new Claim(\"app_specific\", \"some data\"));\r\n\r\n                        context.AuthenticationTicket = new AuthenticationTicket(\r\n                            nid,\r\n                            context.AuthenticationTicket.Properties);\r\n                    },\r\n                    RedirectToIdentityProvider = async f => {\r\n                        //need to populate the redirect link hint\r\n                        if (f.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) {\r\n                            String idTokenHint = f.OwinContext.Authentication.User.FindFirst(\"id_token\").Value;\r\n                            f.ProtocolMessage.IdTokenHint = idTokenHint;\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n\r\n            app.UseResourceAuthorization(new AuthorizationManager());\r\n        }\r\n\r\n        //google external login authorization\r\n        private void ConfigureIdentityProviders(IAppBuilder app, String signInAsType) {\r\n            app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() {\r\n                AuthenticationType = \"Google\",\r\n                Caption = \"Sign in with Google\",\r\n                SignInAsAuthenticationType = signInAsType,\r\n                ClientId = \"*********\",\r\n                ClientSecret = \"***********\",\r\n            });\r\n\r\n            var facebookOptions = new FacebookAuthenticationOptions() {\r\n                AuthenticationType = \"Facebook\",\r\n                Caption = \"Sign in with Facebook\",\r\n                AppId = \"*****\",\r\n                AppSecret = \"****\",\r\n                SignInAsAuthenticationType = signInAsType,\r\n                Provider = new FacebookAuthenticationProvider() {\r\n                    OnAuthenticated = (context) => {\r\n\r\n                        foreach (var x in context.User) {\r\n                            context.Identity.AddClaim(new Claim(x.Key, x.Value.ToString()));\r\n                        }\r\n\r\n                        return Task.FromResult(context);\r\n                    }\r\n                },\r\n            };\r\n\r\n            facebookOptions.Scope.Add(\"email\");\r\n            facebookOptions.Scope.Add(\"public_profile\");\r\n            facebookOptions.Scope.Add(\"user_friends\");\r\n\r\n            app.UseFacebookAuthentication(facebookOptions);\r\n        }\r\n\r\n\r\n        private X509Certificate2 LoadCertificate() {\r\n            return new X509Certificate2(\r\n                string.Format(@\"{0}\\bin\\identityServer\\idsrv3test.pfx\", AppDomain.CurrentDomain.BaseDirectory), \"idsrv3test\");\r\n        }\r\n\r\n    }\r\n```\r\n\r\nI'm quite a noobie with authentication and authorization, I hope I haven't misunderstood the guide..."}}