From 73a88245b17605c9d9cb49d6592e417876f30f2b Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 7 Dec 2020 14:14:11 -0500 Subject: [PATCH] Adds Keycloak OAuth support --- README.md | 3 +- docs/API.dox | 1 + .../Security/OAuth/KeycloakOAuthValidator.cs | 54 +++++++++++++++++++ .../Security/OAuth/OAuthProviders.cs | 8 +++ src/Tgstation.Server.Host/appsettings.json | 3 +- 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/Tgstation.Server.Host/Security/OAuth/KeycloakOAuthValidator.cs diff --git a/README.md b/README.md index 26a84e81dd..841fdb4e12 100644 --- a/README.md +++ b/README.md @@ -143,10 +143,11 @@ The following providers use the `RedirectUrl` setting: - GitHub - TGForums +- Keycloak The following providers use the `ServerUrl` setting: -- None so far +- Keycloak ### Database Configuration diff --git a/docs/API.dox b/docs/API.dox index 5507fa7f83..927d3cd0c5 100644 --- a/docs/API.dox +++ b/docs/API.dox @@ -147,6 +147,7 @@ You will be granted a bearer token as in basic auth. This will have an extended - GitHub: https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/ - Discord: https://discord.com/developers/docs/topics/oauth2 - TGForums: https://tgstation13.org/phpBB/viewtopic.php?f=45&t=9922 +- Keycloak: https://plugins.miniorange.com/keycloak-single-sign-on-wordpress-sso-oauth-openid-connect @section api_perms Permissions diff --git a/src/Tgstation.Server.Host/Security/OAuth/KeycloakOAuthValidator.cs b/src/Tgstation.Server.Host/Security/OAuth/KeycloakOAuthValidator.cs new file mode 100644 index 0000000000..61e08a56ab --- /dev/null +++ b/src/Tgstation.Server.Host/Security/OAuth/KeycloakOAuthValidator.cs @@ -0,0 +1,54 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Net.Http; +using Tgstation.Server.Api.Models; +using Tgstation.Server.Host.Configuration; +using Tgstation.Server.Host.System; + +namespace Tgstation.Server.Host.Security.OAuth +{ + /// + /// OAuth validator for Keycloak. + /// + sealed class KeycloakOAuthValidator : GenericOAuthValidator + { + /// + public override OAuthProvider Provider => OAuthProvider.Keycloak; + + /// + protected override Uri TokenUrl => new Uri($"{BaseProtocolPath}/token"); + + /// + protected override Uri UserInformationUrl => new Uri($"{BaseProtocolPath}/userinfo"); + + /// + /// Base path to the server's OAuth endpoint. + /// + string BaseProtocolPath => $"{OAuthConfiguration.ServerUrl}/protocol/openid-connect"; + + /// + /// Initializes a new instance of the . + /// + /// The for the . + /// The for the . + /// The for the . + /// The for the . + public KeycloakOAuthValidator( + IHttpClientFactory httpClientFactory, + IAssemblyInformationProvider assemblyInformationProvider, + ILogger logger, + OAuthConfiguration oAuthConfiguration) + : base(httpClientFactory, assemblyInformationProvider, logger, oAuthConfiguration) + { + } + + /// + protected override OAuthTokenRequest CreateTokenRequest(string code) => new OAuthTokenRequest(OAuthConfiguration, code, "openid"); + + /// + protected override string DecodeTokenPayload(dynamic responseJson) => responseJson.access_token; + + /// + protected override string DecodeUserInformationPayload(dynamic responseJson) => responseJson.sub; + } +} diff --git a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs index 9087aad25b..e8133706b2 100644 --- a/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs +++ b/src/Tgstation.Server.Host/Security/OAuth/OAuthProviders.cs @@ -66,6 +66,14 @@ namespace Tgstation.Server.Host.Security.OAuth loggerFactory.CreateLogger(), tgConfig)); + if (securityConfiguration.OAuth.TryGetValue(OAuthProvider.Keycloak, out var keyCloakConfig)) + validatorsBuilder.Add( + new KeycloakOAuthValidator( + httpClientFactory, + assemblyInformationProvider, + loggerFactory.CreateLogger(), + keyCloakConfig)); + validators = validatorsBuilder; } diff --git a/src/Tgstation.Server.Host/appsettings.json b/src/Tgstation.Server.Host/appsettings.json index 00506b5762..b0df570838 100644 --- a/src/Tgstation.Server.Host/appsettings.json +++ b/src/Tgstation.Server.Host/appsettings.json @@ -58,7 +58,8 @@ "OAuth": { "GitHub": null, "Discord": null, - "TGForums": null + "TGForums": null, + "Keycloak": null } } }