Got logout working in a hacky way

Added keycloak dev config
This commit is contained in:
Mark Ettema 2021-05-24 09:46:48 +07:00
parent c12ce382d8
commit f24607c4c2
8 changed files with 1885 additions and 21 deletions

File diff suppressed because it is too large Load diff

View file

@ -2,33 +2,47 @@
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks; using System.Threading.Tasks;
using IdentityServer4.Events;
using IdentityServer4.Extensions;
using IdentityServer4.Services;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using SteamOpenIdConnectProvider.Domains.IdentityServer;
namespace SteamOpenIdConnectProvider.Controllers namespace SteamOpenIdConnectProvider.Controllers
{ {
[AllowAnonymous] [AllowAnonymous]
[Route("[action]")]
public class ExternalLoginController : Controller public class ExternalLoginController : Controller
{ {
private readonly SignInManager<IdentityUser> _signInManager; private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager; private readonly UserManager<IdentityUser> _userManager;
private readonly IIdentityServerInteractionService _interaction;
private readonly IEventService _events;
private readonly OpenIdConfig _config;
private readonly ILogger<ExternalLoginController> _logger; private readonly ILogger<ExternalLoginController> _logger;
public ExternalLoginController( public ExternalLoginController(
SignInManager<IdentityUser> signInManager, SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager, UserManager<IdentityUser> userManager,
IIdentityServerInteractionService interaction,
IEventService events,
IOptions<OpenIdConfig> config,
ILogger<ExternalLoginController> logger) ILogger<ExternalLoginController> logger)
{ {
_signInManager = signInManager; _signInManager = signInManager;
_userManager = userManager; _userManager = userManager;
_config = config.Value;
_logger = logger; _logger = logger;
_interaction = interaction;
_events = events;
} }
[HttpGet] [HttpGet("external-login")]
public Task<IActionResult> ExternalLogin(string returnUrl = null) public Task<IActionResult> ExternalLogin(string returnUrl = null)
{ {
const string provider = "Steam"; const string provider = "Steam";
@ -38,7 +52,7 @@ namespace SteamOpenIdConnectProvider.Controllers
return Task.FromResult<IActionResult>(new ChallengeResult(provider, properties)); return Task.FromResult<IActionResult>(new ChallengeResult(provider, properties));
} }
[HttpGet] [HttpGet("external-login-callback")]
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null) public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{ {
returnUrl ??= Url.Content("~/"); returnUrl ??= Url.Content("~/");
@ -97,5 +111,21 @@ namespace SteamOpenIdConnectProvider.Controllers
return BadRequest(); return BadRequest();
} }
[HttpGet("external-logout")]
public async Task<ActionResult> ExternalLogout(string logoutId)
{
var logout = await _interaction.GetLogoutContextAsync(logoutId);
if (User?.Identity.IsAuthenticated == true)
{
await _signInManager.SignOutAsync();
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
}
return Redirect(logout?.PostLogoutRedirectUri ??
_config.PostLogoutRedirectUris.FirstOrDefault() ??
Url.Content("~/"));
}
} }
} }

View file

@ -11,7 +11,7 @@ namespace SteamOpenIdConnectProvider.Models.IdentityServer
{ {
public static IEnumerable<Client> GetClients(OpenIdConfig config) public static IEnumerable<Client> GetClients(OpenIdConfig config)
{ {
yield return new Client var client = new Client
{ {
ClientId = config.ClientID, ClientId = config.ClientID,
ClientName = config.ClientName, ClientName = config.ClientName,
@ -23,10 +23,11 @@ namespace SteamOpenIdConnectProvider.Models.IdentityServer
}, },
// where to redirect to after login // where to redirect to after login
RedirectUris = config.RedirectUri.Split(",").Select(x => x.Trim()).ToArray(), RedirectUris = config.RedirectUris.ToArray(),
// where to redirect to after logout // where to redirect to after logout
PostLogoutRedirectUris = { config.PostLogoutRedirectUri }, PostLogoutRedirectUris = config.PostLogoutRedirectUris.ToArray(),
RequirePkce = false, RequirePkce = false,
AllowedScopes = new List<string> AllowedScopes = new List<string>
{ {
@ -34,6 +35,7 @@ namespace SteamOpenIdConnectProvider.Models.IdentityServer
IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Profile,
} }
}; };
yield return client;
} }
public static IEnumerable<IdentityResource> GetIdentityResources() public static IEnumerable<IdentityResource> GetIdentityResources()

View file

@ -14,5 +14,13 @@ namespace SteamOpenIdConnectProvider.Domains.IdentityServer
public string RedirectUri { get; set; } public string RedirectUri { get; set; }
public string PostLogoutRedirectUri { get; set; } public string PostLogoutRedirectUri { get; set; }
public string ClientName { get; set; } = "Proxy Client"; public string ClientName { get; set; } = "Proxy Client";
public IEnumerable<string> RedirectUris => (RedirectUri ?? string.Empty).Split(
new[] { ',', ';' },
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
public IEnumerable<string> PostLogoutRedirectUris => (PostLogoutRedirectUri ?? string.Empty).Split(
new[] { ',', ';' },
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
} }
} }

View file

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SteamOpenIdConnectProvider.Domains.IdentityServer
{
public static class OpenIdStandardClaims
{
public static readonly string Name = "name";
public static readonly string GivenName = "given_name";
public static readonly string FamilyName = "family_name";
public static readonly string MiddleName = "middle_name";
public static readonly string Nickname = "nickname";
public static readonly string PreferredUsername = "preferred_username";
public static readonly string Profile = "profile";
public static readonly string Picture = "picture";
public static readonly string Website = "website";
public static readonly string Email = "email";
public static readonly string EmailVerified = "email_verified";
public static readonly string Gender = "gender";
public static readonly string BirthDate = "BirthDate";
public static readonly string Zoneinfo = "zoneinfo";
public static readonly string Locale = "locale";
public static readonly string PhoneNumber = "phone_number";
public static readonly string PhoneNumberVerified = "phone_number_verified";
public static readonly string Address = "address";
public static readonly string UpdatedAt = "updated_at";
}
}

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Security.Claims; using System.Security.Claims;
@ -9,6 +9,7 @@ using IdentityServer4.Models;
using IdentityServer4.Services; using IdentityServer4.Services;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SteamOpenIdConnectProvider.Domains.IdentityServer;
using SteamOpenIdConnectProvider.Domains.Steam; using SteamOpenIdConnectProvider.Domains.Steam;
using SteamOpenIdConnectProvider.Models.Steam; using SteamOpenIdConnectProvider.Models.Steam;
@ -49,10 +50,11 @@ namespace SteamOpenIdConnectProvider.Services
if (player != null) if (player != null)
{ {
AddClaim(claims, "picture", player.AvatarFull); AddClaim(claims, OpenIdStandardClaims.Picture, player.AvatarFull);
AddClaim(claims, "nickname", player.PersonaName); AddClaim(claims, OpenIdStandardClaims.Nickname, player.PersonaName);
AddClaim(claims, "given_name", player.RealName); AddClaim(claims, OpenIdStandardClaims.PreferredUsername, player.PersonaName);
AddClaim(claims, "website", player.ProfileUrl); AddClaim(claims, OpenIdStandardClaims.GivenName, player.RealName);
AddClaim(claims, OpenIdStandardClaims.Website, player.ProfileUrl);
} }
context.IssuedClaims = claims; context.IssuedClaims = claims;

View file

@ -46,20 +46,23 @@ namespace SteamOpenIdConnectProvider
.AddEntityFrameworkStores<AppInMemoryDbContext>() .AddEntityFrameworkStores<AppInMemoryDbContext>()
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
var openIdConfig = Configuration.GetSection(OpenIdConfig.Key).Get<OpenIdConfig>(); var openIdConfig = Configuration.GetSection(OpenIdConfig.Key);
services.AddIdentityServer(options => services
.Configure<OpenIdConfig>(openIdConfig)
.AddIdentityServer(options =>
{ {
options.UserInteraction.LoginUrl = "/ExternalLogin"; options.UserInteraction.LoginUrl = "/external-login";
options.UserInteraction.LogoutUrl = "/external-logout";
}) })
.AddAspNetIdentity<IdentityUser>() .AddAspNetIdentity<IdentityUser>()
.AddInMemoryClients(IdentityServerConfigFactory.GetClients(openIdConfig)) .AddInMemoryClients(IdentityServerConfigFactory.GetClients(openIdConfig.Get<OpenIdConfig>()))
.AddInMemoryPersistedGrants() .AddInMemoryPersistedGrants()
.AddDeveloperSigningCredential(true) .AddDeveloperSigningCredential(true)
.AddInMemoryIdentityResources(IdentityServerConfigFactory.GetIdentityResources()); .AddInMemoryIdentityResources(IdentityServerConfigFactory.GetIdentityResources());
var steamConfig = Configuration.GetSection(SteamConfig.Key).Get<SteamConfig>(); var steamConfig = Configuration.GetSection(SteamConfig.Key);
services services
.Configure<SteamConfig>(Configuration.GetSection(SteamConfig.Key)) .Configure<SteamConfig>(steamConfig)
.AddHttpClient<IProfileService, SteamProfileService>(); .AddHttpClient<IProfileService, SteamProfileService>();
services.AddAuthentication() services.AddAuthentication()
@ -70,7 +73,7 @@ namespace SteamOpenIdConnectProvider
}) })
.AddSteam(options => .AddSteam(options =>
{ {
options.ApplicationKey = steamConfig.ApplicationKey; options.ApplicationKey = steamConfig.Get<SteamConfig>().ApplicationKey;
}); });
services.AddHealthChecks() services.AddHealthChecks()

View file

@ -5,7 +5,9 @@
"ClientSecret": "keycloak", "ClientSecret": "keycloak",
"ClientName": "keycloak", "ClientName": "keycloak",
"RedirectUri": "https://dev.local/auth/realms/dev/broker/steam/endpoint", "RedirectUri": "https://dev.local/auth/realms/dev/broker/steam/endpoint",
"PostLogoutRedirectUri": ""
// TODO: Don't think this is how it suppose to work.
"PostLogoutRedirectUri": "https://dev.local/auth/realms/dev/protocol/openid-connect/logout?initiating_idp=steam"
}, },
"Hosting": { "Hosting": {
"BasePath": "" "BasePath": ""