public void Configuration(IAppBuilder app) { AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = "https://localhost:44300/identity", ClientId = "mvc", RedirectUri = "http://localhost:26214/", Scope = "openid profile sampleApi", ResponseType = "id_token token", SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.GivenName, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); } } }); }
public void Configuration(IAppBuilder app) { var options = new UseCookieAuthAgainstTokenServerOptions(EndPointConstants.TokenServer, ClientConstants.MvcClientId, new[] { ClaimTypeKeys.Subject, ClaimTypeKeys.GivenName, ClaimTypeKeys.FamilyName, ClaimTypeKeys.Email, ClaimTypeKeys.Role }) { ResponseType = ResponseType.IdToken | ResponseType.AccessToken, Scopes = new[] { "openid", "profile", "roles", ResourceScopes.SecuredApi }, RedirectUriAfterLogin = EndPointConstants.MvcClient, RedirectUriAfterLogout = EndPointConstants.MvcClient, //OnTransformingValidatedIdentity = async orgIdentity => //{ //}, OnLookupUserInfo = async accesstoken => { var userInfoClient = new UserInfoClient(new Uri(EndPointConstants.TokenServer + "/connect/userinfo"), accesstoken); var userInfo = await userInfoClient.GetAsync(); var claims = new List<Claim>(); userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2))); return claims.ToArray(); } }; app.UseCookieAuthAgainstTokenServer(options); }
public async Task <UserInfoResponse> GetUserInfoAsync(string accessToken) { var userInfoClient = new IdentityModel.Client.UserInfoClient( new Uri(baseUrl.EnsureTrailingSlash() + "connect/userinfo"), accessToken); return(await userInfoClient.GetAsync()); }
public async Task<UserInfoResponse> GetUserInfo(Uri userInfoEndpoint, string accessToken) { var userInfoClient = new UserInfoClient(userInfoEndpoint.ToString()); var response = await userInfoClient.GetAsync(accessToken).ConfigureAwait(false); if (response.IsError) throw new Exception( $"Error while retrieving userinfo: {response.Error} {response.HttpStatusCode}"); return new UserInfoResponse(response.Raw); }
static void GetClaims(string token) { var client = new UserInfoClient( new Uri(Constants.UserInfoEndpoint), token); var response = client.GetAsync().Result; var identity = response.GetClaimsIdentity(); "\n\nUser claims:".ConsoleGreen(); foreach (var claim in identity.Claims) { Console.WriteLine("{0}\n {1}", claim.Type, claim.Value); } }
private static async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) { // 1) Use the code to get the access and refresh token, // As we are using the hybrid flow, we will get a "code" and "access_token" but not "refresh_token". // Using the code we can get a "refresh_token" if the client application is a server side app (like this example) // If the application is a SPA or a native phone app, it is not secure to use the ClientSecret var tokenClient = new TokenClient(Constants.TokenEndpoint, Constants.ClientId, Constants.ClientSecret); var tokensResponse = tokenClient.RequestAuthorizationCodeAsync(context.Code, context.RedirectUri).Result; var expiration = DateTime.Now.AddSeconds(tokensResponse.ExpiresIn) .ToLocalTime() .ToString(CultureInfo.InvariantCulture); List<Claim> oauthClaims = new List<Claim> { new Claim("access_token", tokensResponse.AccessToken), new Claim("refresh_token", tokensResponse.RefreshToken), new Claim("expires_at", expiration) }; // 2) Use the access token to retrieve user info claims // The access token is a JWT token, it can be used to secure WebApi var userInfoClient = new UserInfoClient(new Uri(Constants.UserInfoEndpoint), tokensResponse.AccessToken); var userInfo = await userInfoClient.GetAsync(); List<Claim> userClaims = userInfo.Claims.Select(ui => new Claim(ui.Item1, ui.Item2)).ToList(); // 3) Add claims to authentication ticket ClaimsIdentity identity = context.AuthenticationTicket.Principal.Identity as ClaimsIdentity; if (identity != null) { // Remove all protocol related claims var claimsToRemove = identity.Claims.ToList(); foreach (var claim in claimsToRemove) { identity.RemoveClaim(claim); } // Add oauth and user claims identity.AddClaims(oauthClaims); identity.AddClaims(userClaims); } }
public async Task Address_Scope() { var tokenClient = new TokenClient( TokenEndpoint, "roclient", "secret", innerHttpMessageHandler: _handler); var response = await tokenClient.RequestResourceOwnerPasswordAsync("bob", "bob", "openid address"); response.IsError.Should().BeFalse(); var userInfoclient = new UserInfoClient( new Uri(UserInfoEndpoint), response.AccessToken, _handler); var userInfo = await userInfoclient.GetAsync(); userInfo.IsError.Should().BeFalse(); userInfo.Raw.Should().Be("{\"sub\":\"88421113\",\"address\":{\"street_address\":\"One Hacker Way\",\"locality\":\"Heidelberg\",\"postal_code\":69118,\"country\":\"Germany\"}}"); }
public async Task Valid_Client() { var tokenClient = new TokenClient( TokenEndpoint, "roclient", "secret", innerHttpMessageHandler: _handler); var response = await tokenClient.RequestResourceOwnerPasswordAsync("bob", "bob", "openid email api1"); response.IsError.Should().BeFalse(); var userInfoclient = new UserInfoClient( new Uri(UserInfoEndpoint), response.AccessToken, _handler); var userInfo = await userInfoclient.GetAsync(); userInfo.IsError.Should().BeFalse(); userInfo.Claims.Count().Should().Be(3); userInfo.Claims.Should().Contain(Tuple.Create("sub", "88421113")); userInfo.Claims.Should().Contain(Tuple.Create("email", "*****@*****.**")); userInfo.Claims.Should().Contain(Tuple.Create("email_verified", "True")); }
public void Configuration(IAppBuilder app) { JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = "mvc.owin.hybrid", Authority = Constants.BaseAddress, RedirectUri = "https://localhost:44300/", PostLogoutRedirectUri = "https://localhost:44300/", ResponseType = "code id_token", Scope = "openid profile read write offline_access", TokenValidationParameters = new TokenValidationParameters { NameClaimType = "name", RoleClaimType = "role" }, SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { AuthorizationCodeReceived = async n => { // use the code to get the access and refresh token var tokenClient = new TokenClient( Constants.TokenEndpoint, "mvc.owin.hybrid", "secret"); var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync( n.Code, n.RedirectUri); if (tokenResponse.IsError) { throw new Exception(tokenResponse.Error); } // use the access token to retrieve claims from userinfo var userInfoClient = new UserInfoClient( new Uri(Constants.UserInfoEndpoint), tokenResponse.AccessToken); var userInfoResponse = await userInfoClient.GetAsync(); // create new identity var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType); id.AddClaims(userInfoResponse.GetClaimsIdentity().Claims); id.AddClaim(new Claim("access_token", tokenResponse.AccessToken)); id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString())); id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken)); id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value)); n.AuthenticationTicket = new AuthenticationTicket( new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"), n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { // if signing out, add the id_token_hint if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType, }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = "http://localhost:8896/identity", ClientId = "SEMS", Scope = "openid profile", ResponseType = "id_token token", RedirectUri = "http://localhost:60544/", PostLogoutRedirectUri= "http://localhost:60544/", SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType, UseTokenLifetime = false, Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = Constantes.CustomAuthenticationTypes.Cookies, LoginPath = new PathString("/Account/Login") }); #region Implicitit Authentication app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { //servidor de autenticação Authority = ConfigurationManager.AppSettings[Constantes.AppSettings.Authority]+"/", //Id desta aplicação, não precisa de senha ClientId = ConfigurationManager.AppSettings[Constantes.AppSettings.ClientId], //Tem que especificar qual escopo o cliente quer ter acesso Scope = ConfigurationManager.AppSettings[Constantes.AppSettings.Scopes], //precisa que a resposta contenha um token de autenticação ResponseType = ConfigurationManager.AppSettings[Constantes.AppSettings.ResponseType], //Uri desta aplicação com SSL RedirectUri = ConfigurationManager.AppSettings[Constantes.AppSettings.RedirectUri], PostLogoutRedirectUri = ConfigurationManager.AppSettings[Constantes.AppSettings.PostLogoutRedirectUri], SignInAsAuthenticationType = Constantes.CustomAuthenticationTypes.Cookies, UseTokenLifetime = Boolean.Parse(ConfigurationManager.AppSettings[Constantes.AppSettings.UseTokenLifetime]), //Quando o cara faz login com sucesso Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.Name, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/" + Constants.RoutePaths.Oidc.UserInfo), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim(Constants.ResponseTypes.IdToken, n.ProtocolMessage.IdToken)); // add access token for API nid.AddClaim(new Claim(Constants.TokenTypes.AccessToken, n.ProtocolMessage.AccessToken)); // mantem o momento da expiração do token nid.AddClaim(new Claim( Constantes.CustomTokenResponse.ExpiresAt, DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString() )); // add some other app specific claim n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); }, #region CONFIGURAÇÃO NECESSÁRIA PARA QUE O USUARIO SEJA REDIRECIONADO DE VOLTAR PARA A APLICAÇÃO APÓS O LOGOUT //quando for redirecionado para o identity provider e for um solicitação do LogOut, precisa guardar o id_token no id_token_hint senão o //Identity Server não redireciona de volta. RedirectToIdentityProvider = n => { if(n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst(Constants.ResponseTypes.IdToken); if(idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } #endregion } }); #endregion }
public void Configuration(IAppBuilder app) { JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = "katanaclient", Authority = Constants.BaseAddress, RedirectUri = "http://localhost:2672/", PostLogoutRedirectUri = "http://localhost:2672/", ResponseType = "code id_token token", Scope = "openid email profile read write offline_access", SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { AuthorizationCodeReceived = async n => { // get userinfo data var userInfoClient = new UserInfoClient( new Uri(Constants.UserInfoEndpoint), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); var id = userInfo.GetClaimsIdentity(); // get access and refresh token var tokenClient = new TokenClient( Constants.TokenEndpoint, "katanaclient", "secret"); var response = await tokenClient.RequestAuthorizationCodeAsync(n.Code, n.RedirectUri); id.AddClaim(new Claim("access_token", response.AccessToken)); id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(response.ExpiresIn).ToLocalTime().ToString())); id.AddClaim(new Claim("refresh_token", response.RefreshToken)); id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); n.AuthenticationTicket = new AuthenticationTicket( new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType), n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { // if signing out, add the id_token_hint if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
public void Configuration(IAppBuilder app) { AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.Map( "/identity", idsrvApp => { idsrvApp.UseIdentityServer( new IdentityServerOptions { SiteName = "Embedded IdentityServer", SigningCertificate = LoadCertificate(), Factory = new IdentityServerServiceFactory().UseInMemoryUsers( Users.Get()) .UseInMemoryClients(Clients.Get()) .UseInMemoryScopes(Scopes.Get()), // Use this for Facebook login //AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions //{ // IdentityProviders = ConfigureIdentityProviders //} }); }); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); // Point the OpenID Connect middleware (also in Startup.cs) to our embedded version of IdentityServer and use the previously configured client configuration app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { Authority = "https://localhost:44301/identity", ClientId = "mvc", Scope = "openid profile roles sampleApi", RedirectUri = "https://localhost:44301/", ResponseType = "id_token token", SignInAsAuthenticationType = "Cookies", UseTokenLifetime = false, // Do the claims transformations Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.GivenName, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for Logout - the client has to prove its identity to the // logout endpoint to make sure we redirect to the right URL (and not some spammer/phishing page). nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); }, // attach the id_token when the user logs out and we make the roundtrip to IdentityServer. RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); app.UseResourceAuthorization(new AuthorizationManager()); }
public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions() { AuthenticationType = "Cookies", ExpireTimeSpan = TimeSpan.FromMinutes(10), SlidingExpiration = true }); JwtSecurityTokenHandler.InboundClaimTypeMap.Clear(); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { AuthenticationType = "oidc", SignInAsAuthenticationType = "Cookies", Authority = "https://localhost:44333/core/", ClientId = "webforms.owin.implicit", RedirectUri = "http://localhost:5969/", PostLogoutRedirectUri = "http://localhost:5969/", ResponseType = "id_token token", Scope = "openid profile email", UseTokenLifetime = false, Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var claims_to_exclude = new[] { "aud", "iss", "nbf", "exp", "nonce", "iat", "at_hash" }; var claims_to_keep = n.AuthenticationTicket.Identity.Claims .Where(x => false == claims_to_exclude.Contains(x.Type)).ToList(); claims_to_keep.Add(new Claim("id_token", n.ProtocolMessage.IdToken)); if (n.ProtocolMessage.AccessToken != null) { claims_to_keep.Add(new Claim("access_token", n.ProtocolMessage.AccessToken)); var userInfoClient = new UserInfoClient(new Uri("https://localhost:44333/core/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfoResponse = await userInfoClient.GetAsync(); var userInfoClaims = userInfoResponse.Claims .Where(x => x.Item1 != "sub") // filter sub since we're already getting it from id_token .Select(x => new Claim(x.Item1, x.Item2)); claims_to_keep.AddRange(userInfoClaims); } var ci = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"); ci.AddClaims(claims_to_keep); n.AuthenticationTicket = new Microsoft.Owin.Security.AuthenticationTicket( ci, n.AuthenticationTicket.Properties ); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var id_token = n.OwinContext.Authentication.User.FindFirst("id_token")?.Value; n.ProtocolMessage.IdTokenHint = id_token; } return Task.FromResult(0); } } }); app.UseStageMarker(PipelineStage.Authenticate); }
public async Task No_Identity_Scope() { var tokenClient = new TokenClient( TokenEndpoint, "roclient", "secret", innerHttpMessageHandler: _handler); var response = await tokenClient.RequestResourceOwnerPasswordAsync("bob", "bob", "api1"); response.IsError.Should().BeFalse(); var userInfoclient = new UserInfoClient( new Uri(UserInfoEndpoint), response.AccessToken, _handler); var userInfo = await userInfoclient.GetAsync(); userInfo.IsError.Should().BeTrue(); userInfo.HttpErrorStatusCode.Should().Be(HttpStatusCode.Forbidden); }
public async Task<ActionResult> Album(Guid tripId) { var token = (User.Identity as ClaimsIdentity).FindFirst("access_token").Value; UserInfoClient userInfoClient = new UserInfoClient( new Uri(Constants.TripGallerySTSUserInfoEndpoint), token ); var userInfoResponse = await userInfoClient.GetAsync(); if(! userInfoResponse.IsError ) { //create object to return (dynamic Expando - anonnymous) //types won't allow accessto their properties from the view dynamic addressInfo = new ExpandoObject(); addressInfo.Address = userInfoResponse.Claims.First(c => c.Item1 == "address").Item2; return View(addressInfo); } else{ var exception = new Exception("Problem getting your address. Please contact your administrator"); return View("Error", new HandleErrorInfo(exception, "Trips", "Album")); } return View(); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug(); if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseIISPlatformHandler(); app.UseStaticFiles(); app.UseCookieAuthentication(options => { options.AuthenticationScheme = "cookies"; options.AutomaticAuthenticate = true; options.AutomaticChallenge = true; }); app.UseCors(policy => { policy.AllowAnyOrigin(); policy.AllowAnyHeader(); policy.AllowAnyMethod(); }); JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); app.UseOpenIdConnectAuthentication(options => { options.AuthenticationScheme = "oidc"; options.SignInScheme = "cookies"; options.AutomaticChallenge = true; options.Authority = SharedConfiguration.Constants.BaseAddress; options.RequireHttpsMetadata = false; options.ClientId = "implicitclient"; options.ResponseType = "id_token token"; options.SaveTokensAsClaims = true; options.Scope.Add("openid"); options.Scope.Add("email"); options.Scope.Add("roles"); options.Scope.Add("all_claims"); //options.TokenValidationParameters.NameClaimType = "name"; //options.TokenValidationParameters.RoleClaimType = "role"; options.PostLogoutRedirectUri = "http://localhost:53692"; options.Events = new OpenIdConnectEvents { OnRedirectToAuthenticationEndpoint = context => { if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = context.HttpContext.User.FindFirst("id_token"); if (idTokenHint != null) { context.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); }, OnAuthenticationValidated = async context => { var nid = new ClaimsIdentity(context.AuthenticationTicket.Principal.Identity.AuthenticationType, "name", "role"); var userInfoClient = new UserInfoClient(new Uri(context.Options.Authority + "/connect/userinfo"), context.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new System.Security.Claims.Claim(ui.Item1, ui.Item2))); // manter o id_token para fazer logout nid.AddClaim(new System.Security.Claims.Claim("id_token", context.ProtocolMessage.IdToken)); nid.AddClaim(new System.Security.Claims.Claim("access_token", context.ProtocolMessage.AccessToken)); nid.AddClaim(new System.Security.Claims.Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(context.ProtocolMessage.ExpiresIn)).ToString())); context.AuthenticationTicket = new AuthenticationTicket(new ClaimsPrincipal(nid), context.AuthenticationTicket.Properties, context.AuthenticationTicket.AuthenticationScheme); } }; }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
public void Configuration(IAppBuilder app) { string baseAddress = "https://localhost:44333/core"; string tokenEndpoint = baseAddress + "/connect/token"; string userInfoEndpoint = baseAddress + "/connect/userinfo"; string clientAddress = "https://localhost:44302/"; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions() { ClientId = "katanaclient", Authority = baseAddress, RedirectUri = clientAddress, PostLogoutRedirectUri = clientAddress, ResponseType = "code id_token", Scope = "openid profile roles read write offline_access", SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { AuthorizationCodeReceived = async n => { var tokenClient = new TokenClient( tokenEndpoint, "katanaclient", "secret"); var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync( n.Code, n.RedirectUri); if (tokenResponse.AccessToken != null) { var userInfoClient = new UserInfoClient( new Uri(userInfoEndpoint), tokenResponse.AccessToken); var userInfoResponse = await userInfoClient.GetAsync(); var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType); var userClaims = userInfoResponse.GetClaimsIdentity().Claims.ToList(); if (userClaims.Any()) { id.AddClaims(userClaims); foreach (var claim in userClaims.Where(x => x.Type == "role")) { id.AddClaim(new Claim(ClaimTypes.Role, claim.Value)); } } if (tokenResponse.AccessToken != null) id.AddClaim(new Claim("access_token", tokenResponse.AccessToken)); var localExpiresIn = DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime(); if (localExpiresIn != null) { id.AddClaim(new Claim("expires_at", localExpiresIn .ToString(CultureInfo.InvariantCulture))); } if (tokenResponse.RefreshToken != null) id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken)); if (n.ProtocolMessage.IdToken != null) id.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity .FindFirst("sid").Value)); n.AuthenticationTicket = new AuthenticationTicket( new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType), n.AuthenticationTicket.Properties); } }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User .FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
private async Task<IEnumerable<Claim>> GetUserInfoClaimsAsync(string accessToken) { var userInfoClient = new UserInfoClient(new Uri(Constants.UserInfoEndpoint), accessToken); var userInfo = await userInfoClient.GetAsync(); var claims = new List<Claim>(); userInfo.Claims.ToList().ForEach(ui => claims.Add(new Claim(ui.Item1, ui.Item2))); return claims; }
public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = IdealConstants.ClientId, Authority = IdealConstants.STSOrigin, RedirectUri = IdealConstants.ClientOrigin, SignInAsAuthenticationType = "Cookies", ResponseType = "code id_token token", Scope = "sampleApi", Notifications = new OpenIdConnectAuthenticationNotifications() { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.GivenName, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(IdealConstants.STSUserInfoEndpoint), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
private async Task<LoginResult> ValidateResponseAsync(AuthorizeResponse response) { // id_token validieren var tokenClaims = ValidateIdentityToken(response.IdentityToken); if (tokenClaims == null) { return new LoginResult { ErrorMessage = "Invalid identity token." }; } // nonce validieren var nonce = tokenClaims.FirstOrDefault(c => c.Type == JwtClaimTypes.Nonce); if (nonce == null || !string.Equals(nonce.Value, _nonce, StringComparison.Ordinal)) { return new LoginResult { ErrorMessage = "Inalid nonce." }; } // c_hash validieren var c_hash = tokenClaims.FirstOrDefault(c => c.Type == JwtClaimTypes.AuthorizationCodeHash); if (c_hash == null || ValidateCodeHash(c_hash.Value, response.Code) == false) { return new LoginResult { ErrorMessage = "Invalid code." }; } _provider = JwkNetExtensions.CreateProvider(); var jwk = _provider.ToJsonWebKey(); // code eintauschen gegen tokens var tokenClient = new TokenClient( _config.TokenEndpoint, _settings.ClientId, _settings.ClientSecret); var tokenResponse = await tokenClient.RequestAuthorizationCodePopAsync( code: response.Code, redirectUri: _settings.RedirectUri, codeVerifier: _verifier, algorithm: jwk.Alg, key: jwk.ToJwkString()); if (tokenResponse.IsError) { return new LoginResult { ErrorMessage = tokenResponse.Error }; } // optional userinfo aufrufen var profileClaims = new List<Claim>(); if (_settings.LoadUserProfile) { var userInfoClient = new UserInfoClient( new Uri(_config.UserInfoEndpoint), tokenResponse.AccessToken); var userInfoResponse = await userInfoClient.GetAsync(); profileClaims = userInfoResponse.GetClaimsIdentity().Claims.ToList(); } var principal = CreatePrincipal(tokenClaims, profileClaims); return new LoginResult { Success = true, User = principal, IdentityToken = response.IdentityToken, AccessToken = tokenResponse.AccessToken, RefreshToken = tokenResponse.RefreshToken, AccessTokenExpiration = DateTime.Now.AddSeconds(tokenResponse.ExpiresIn) }; }
// 有关配置身份验证的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkId=301864 public void ConfigureAuth(IAppBuilder app) { JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { ClientId = "sts", Authority = Constants.BaseAddress, RedirectUri = "http://www.a.com/", ResponseType = "id_token token", //Scope = "openid email write", SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, IdentityServer3.Core.Constants.ClaimTypes.GivenName, IdentityServer3.Core.Constants.ClaimTypes.Role); //// get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
private async Task<LoginResult> ValidateAsync(AuthorizeResult result) { // validate identity token var principal = await ValidateIdentityTokenAsync(result.IdentityToken); if (principal == null) { return new LoginResult { Success = false, Error = "identity token validation error" }; } // validate nonce var tokenNonce = principal.FindFirst("nonce")?.Value ?? ""; if (!string.Equals(result.Nonce, tokenNonce)) { return new LoginResult { Success = false, Error = "invalid nonce" }; } // validate audience var audience = principal.FindFirst("aud")?.Value ?? ""; if (!string.Equals(_options.ClientId, audience)) { return new LoginResult { Success = false, Error = "invalid audience" }; } // validate c_hash var cHash = principal.FindFirst("c_hash")?.Value ?? ""; var sha256 = HashAlgorithmProvider.OpenAlgorithm("SHA256"); var codeHash = sha256.HashData( CryptographicBuffer.CreateFromByteArray( Encoding.ASCII.GetBytes(result.Code))); byte[] codeHashArray; CryptographicBuffer.CopyToByteArray(codeHash, out codeHashArray); byte[] leftPart = new byte[16]; Array.Copy(codeHashArray, leftPart, 16); var leftPartB64 = Base64Url.Encode(leftPart); if (!leftPartB64.Equals(cHash)) { return new LoginResult { Success = false, Error = "invalid code" }; } var endpoints = await _options.GetEndpointsAsync(); // get access token var tokenClient = new TokenClient(endpoints.Token, _options.ClientId, _options.ClientSecret); var tokenResult = await tokenClient.RequestAuthorizationCodeAsync( result.Code, result.RedirectUri, codeVerifier: result.Verifier); if (tokenResult.IsError || tokenResult.IsHttpError) { return new LoginResult { Success = false, Error = tokenResult.Error }; } // get profile if enabled if (_options.LoadProfile) { var userInfoClient = new UserInfoClient(new Uri(endpoints.UserInfo), tokenResult.AccessToken); var userInfoResponse = await userInfoClient.GetAsync(); var primaryClaimTypes = principal.Claims.Select(c => c.Type).Distinct(); foreach (var claim in userInfoResponse.Claims.Where(c => !primaryClaimTypes.Contains(c.Item1))) { principal.Identities.First().AddClaim(new Claim(claim.Item1, claim.Item2)); } } // success return new LoginResult { Success = true, Principal = FilterProtocolClaims(principal), AccessToken = tokenResult.AccessToken, RefreshToken = tokenResult.RefreshToken, AccessTokenExpiration = DateTime.Now.AddSeconds(tokenResult.ExpiresIn), IdentityToken = result.IdentityToken, AuthenticationTime = DateTime.Now }; }
private static IEnumerable<Claim> GetUserClaims(string token) { var client = new UserInfoClient( new Uri(Constants.UserInfoEndpoint), token); var response = client.GetAsync().Result; var identity = response.GetClaimsIdentity(); //PrintClaims(identity.Claims); return identity.Claims; }
public void Configuration(IAppBuilder app) { AntiForgeryConfig.UniqueClaimTypeIdentifier = "sub"; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = Constants.IdentityServerUri, ClientId = Constants.ImplicitClient, Scope = "openid profile roles apiAccess", RedirectUri = Constants.ImplicitClientUri, ResponseType = "id_token token", UseTokenLifetime = false, SignInAsAuthenticationType = "Cookies", Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, "givenname", "role"); // get userinfo data var userInfoClient = new UserInfoClient(new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); if (userInfo.Claims != null) { userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); } // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.PostLogoutRedirectUri = Constants.ImplicitClientUri; n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); app.UseResourceAuthorization(new AuthorizationManager()); }
private async System.Threading.Tasks.Task<bool> FinishLoginAsync(TokenResponse response) { // Let's retrieve the claims using that access token to fetch the user name we need. // Note: the user name is already in our response's access token, but this code demonstrates retrieving all claims. var userInfoRequest = new UserInfoClient(new Uri(TimesheetConstants.UserInfoEndpoint), response.AccessToken); var userInfo = await userInfoRequest.GetAsync(); if (userInfo.IsError || userInfo.IsHttpError) { return false; } // Set the EmployeeId needed to create time registrations. App.EmployeeId = userInfo.Claims.FirstOrDefault(x => x.Item1 == "name")?.Item2 ?? ""; // Remember the access token when calling the API _apiService.TokenResponse = response; NavigateToDetailPage(); return true; }
public void Configuration(IAppBuilder app) { // todo: replace with serilog //LogProvider.SetCurrentLogProvider(new DiagnosticsTraceLogProvider()); AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.Map("/identity", idsrvApp => { idsrvApp.UseIdentityServer(new IdentityServerOptions { SiteName = "Embedded IdentityServer", SigningCertificate = LoadCertificate(), Factory = new IdentityServerServiceFactory() .UseInMemoryUsers(Users.Get()) .UseInMemoryClients(Clients.Get()) .UseInMemoryScopes(Scopes.Get()), AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions { IdentityProviders = ConfigureIdentityProviders } }); }); app.UseResourceAuthorization(new AuthorizationManager()); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Cookies" }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = "https://localhost:44319/identity", ClientId = "mvc", Scope = "openid profile roles sampleApi", ResponseType = "id_token token", RedirectUri = "https://localhost:44319/", SignInAsAuthenticationType = "Cookies", UseTokenLifetime = false, Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity( n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.GivenName, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket( nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }
public void Configuration(IAppBuilder app) { AntiForgeryConfig.UniqueClaimTypeIdentifier = Constants.ClaimTypes.Subject; JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>(); app.Map("/identity", coreApp => { var factory = new IdentityServerServiceFactory() .UseInMemoryClients(Clients.Get()) .UseInMemoryScopes(Scopes.Get()); factory.ViewService = new Registration<IViewService>(typeof(ViewService)); factory.UserService = new Registration<IUserService, UserService>(); var options = new IdentityServerOptions { SiteName = "SEMS-SSO", RequireSsl = false, SigningCertificate = Certificate.Get(), Factory = factory, AuthenticationOptions = new IdentityServer3.Core.Configuration.AuthenticationOptions { EnablePostSignOutAutoRedirect = true, EnableSignOutPrompt = false, InvalidSignInRedirectUrl = _ssoUrl }, }; coreApp.UseIdentityServer(options); }); app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType, }); app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions { Authority = _ssoUrl.TrimEnd('/') + "/identity", ClientId = "SEMS-SSO", Scope = "openid profile", ResponseType = "id_token token", RedirectUri = _ssoUrl, PostLogoutRedirectUri = _ssoUrl, SignInAsAuthenticationType = OpenIdConnectAuthenticationDefaults.AuthenticationType, UseTokenLifetime = false, Notifications = new OpenIdConnectAuthenticationNotifications { SecurityTokenValidated = async n => { var nid = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, Constants.ClaimTypes.Name, Constants.ClaimTypes.Role); // get userinfo data var userInfoClient = new UserInfoClient( new Uri(n.Options.Authority + "/connect/userinfo"), n.ProtocolMessage.AccessToken); var userInfo = await userInfoClient.GetAsync(); userInfo.Claims.ToList().ForEach(ui => nid.AddClaim(new Claim(ui.Item1, ui.Item2))); // keep the id_token for logout nid.AddClaim(new Claim("id_token", n.ProtocolMessage.IdToken)); // add access token for sample API nid.AddClaim(new Claim("access_token", n.ProtocolMessage.AccessToken)); // keep track of access token expiration nid.AddClaim(new Claim("expires_at", DateTimeOffset.Now.AddSeconds(int.Parse(n.ProtocolMessage.ExpiresIn)).ToString())); // add some other app specific claim nid.AddClaim(new Claim("app_specific", "some data")); n.AuthenticationTicket = new AuthenticationTicket(nid, n.AuthenticationTicket.Properties); }, RedirectToIdentityProvider = n => { if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest) { var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token"); if (idTokenHint != null) { n.ProtocolMessage.IdTokenHint = idTokenHint.Value; } } return Task.FromResult(0); } } }); }