public async Task BackChannelLogout() { getOIDCConfig = ConsulExtensions.FetchConsul(configuration["Consul:Host"], configuration["Consul:Key"]); string session_id = ""; var claim_sessionid = User.Claims.Where(x => x.Type == "session_id").FirstOrDefault(); if (claim_sessionid != null) { session_id = claim_sessionid.Value; } try { var request = HttpContext.Request; var postLogoutRedirectUri = getOIDCConfig.OIDC.Protocol + "://" + request.Host + request.PathBase + getOIDCConfig.OIDC.PostLogoutRedirectUri; HttpClient client = new HttpClient(); var responseString = client.GetStringAsync($"https://" + getOIDCConfig.OIDC.Domain + "/" + getOIDCConfig.OIDC.CustomPath + "/restv1/end_session?session_id=" + session_id + $"&post_logout_redirect_uri = { Uri.EscapeDataString(postLogoutRedirectUri) }"); } catch (Exception ex) { } finally { HttpContext.Session.Clear(); await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); } //await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(Options => Options.AddPolicy("AllowAll", p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader())); //consul getOIDCConfig = services.FetchConsul(Configuration["Consul:Host"], Configuration["Consul:Key"]); //localization services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; }); services.AddTransient <AppAcessService>(); services.AddMvc() .AddViewLocalization( LanguageViewLocationExpanderFormat.Suffix, opts => { opts.ResourcesPath = "Resources"; }) .AddDataAnnotationsLocalization(); services.AddSession(); // ... previous configuration not shown services.Configure <RequestLocalizationOptions>( opts => { var supportedCultures = new List <CultureInfo> { new CultureInfo("en"), new CultureInfo("fr"), new CultureInfo("el"), }; opts.DefaultRequestCulture = new RequestCulture("en"); // Formatting numbers, dates, etc. opts.SupportedCultures = supportedCultures; // UI strings that we have localized. opts.SupportedUICultures = supportedCultures; }); //localization end services.Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); services.Configure <CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); // Add authentication services services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect("oidc", options => { // Set the authority to your oidc domain options.Authority = $"https://" + getOIDCConfig.OIDC.Domain; // Configure the oidc Client ID and Client Secret options.ClientId = getOIDCConfig.OIDC.ClientId; options.ClientSecret = getOIDCConfig.OIDC.ClientSecret; // Set response type to code //options.ResponseType = "code id_token"; options.ResponseType = "code"; // Configure the scope options.Scope.Clear(); options.Scope.Add("openid"); options.Scope.Add("profile"); options.Scope.Add("email"); options.GetClaimsFromUserInfoEndpoint = true; // Set the callback path, so oidc will call back to http://localhost:5000/signin-oidc // Also ensure that you have added the URL as an Allowed Callback URL in your oidc dashboard options.CallbackPath = new PathString(getOIDCConfig.OIDC.CallbackPath); // Configure the Claims Issuer to be oidc options.ClaimsIssuer = "oidc"; // Saves tokens to the AuthenticationProperties options.SaveTokens = true; options.Events = new OpenIdConnectEvents { OnRedirectToIdentityProvider = notification => { getOIDCConfig = ConsulExtensions.FetchConsul(Configuration["Consul:Host"], Configuration["Consul:Key"]); var ui_locales = notification.HttpContext.Request.Headers["ui_locales"]; var request = notification.Request; var redirectUri = getOIDCConfig.OIDC.Protocol + "://" + request.Host + request.PathBase + getOIDCConfig.OIDC.RedirectUri; // Add custom redirect_uri to avoid the app from guessing it based in the running web server and have issues with a reverse-proxy. notification.ProtocolMessage.RedirectUri = redirectUri; //Uncomment - when Passing ACR values if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication) { //notification.ProtocolMessage.AcrValues = "icrypto"; notification.ProtocolMessage.Parameters.Add("ui_locales", ui_locales.ToString()); } return(Task.FromResult(0)); }, //Get User info using access_token and bind to UI OnTokenResponseReceived = async auth => { string role = ""; var userInfoClient = new UserInfoClient($"https://" + getOIDCConfig.OIDC.Domain + "/" + getOIDCConfig.OIDC.CustomPath + "/restv1/userinfo"); var userInfoResponse = await userInfoClient.GetAsync(auth.TokenEndpointResponse.AccessToken); foreach (var item in userInfoResponse.Claims) { if (item.Type == "roles") { role = item.Value; } } var exp = auth.TokenEndpointResponse.Parameters; var ProtocolMessage = auth.ProtocolMessage.Parameters; OIDCTokenResponse token = new OIDCTokenResponse { AccessToken = exp["access_token"], RefreshToken = exp["refresh_token"], IdToken = exp["id_token"], Type = exp["token_type"], ExpiresIn = exp["expires_in"] }; OIDCCallbackResponse callback = new OIDCCallbackResponse { Code = ProtocolMessage["code"], Scope = ProtocolMessage["scope"], //SessionId = ProtocolMessage["session_id"], //SessionState = ProtocolMessage["session_state"], }; string tokenInfo = JsonConvert.SerializeObject(token); string callbackInfo = JsonConvert.SerializeObject(callback); claims.Clear(); claims.AddRange(userInfoResponse.Claims); claims.Add(new Claim(ClaimTypes.Role, role)); claims.Add(new Claim("tokenInfo", tokenInfo)); claims.Add(new Claim("callbackInfo", callbackInfo)); claims.Add(new Claim("session_id", auth.ProtocolMessage.Parameters["session_id"])); if (!string.IsNullOrEmpty(auth.TokenEndpointResponse.RefreshToken)) { //claims.Add(new Claim("refresh_token", auth.TokenEndpointResponse.RefreshToken)); } id_token = auth.TokenEndpointResponse.IdToken; claims.Add(new Claim("introspect_token", Introspect(auth.TokenEndpointResponse.AccessToken))); return; }, //Add Other claims like access_token, id_token etc.. OnUserInformationReceived = auth => { ClaimsIdentity _claims = new ClaimsIdentity(); _claims.AddClaims(claims); auth.Principal.AddIdentity(_claims); return(Task.FromResult(0)); }, // handle the logout redirection OnRedirectToIdentityProviderForSignOut = (context) => { context.ProtocolMessage.IdTokenHint = id_token; var logoutUri = $"https://" + getOIDCConfig.OIDC.Domain + "/" + getOIDCConfig.OIDC.CustomPath + "/restv1/end_session?id_token_hint=" + context.ProtocolMessage.IdTokenHint; var postLogoutUri = context.Properties.RedirectUri; if (!string.IsNullOrEmpty(postLogoutUri)) { if (postLogoutUri.StartsWith("/")) { // transform to absolute var request = context.Request; postLogoutUri = getOIDCConfig.OIDC.Protocol + "://" + request.Host + request.PathBase + postLogoutUri; } logoutUri += $"&post_logout_redirect_uri={ Uri.EscapeDataString(postLogoutUri)}"; } context.Response.Redirect(logoutUri); context.HandleResponse(); return(Task.CompletedTask); } }; }); services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Latest); }