Added classes for the Configuration

Separated the logic in domains
This commit is contained in:
Mark Ettema 2021-05-09 21:20:57 +07:00
parent e8520a6128
commit 03947fdbdc
11 changed files with 113 additions and 51 deletions

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SteamOpenIdConnectProvider.Domains.Common
{
public class HostingConfig
{
public static readonly string Key = "Hosting";
public string BasePath { get; set; }
public string PublicOrigin { get; set; }
}
}

View file

@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace SteamOpenIdConnectProvider.Database
namespace SteamOpenIdConnectProvider.Domains.IdentityServer
{
// This is completely in-memory, we do not need a persistent store.
public class AppInMemoryDbContext : IdentityDbContext<IdentityUser>

View file

@ -3,29 +3,30 @@ using System.Collections.Generic;
using System.Linq;
using IdentityServer4;
using IdentityServer4.Models;
using SteamOpenIdConnectProvider.Domains.IdentityServer;
namespace SteamOpenIdConnectProvider
namespace SteamOpenIdConnectProvider.Models.IdentityServer
{
public class IdentityServerConfig
public static class IdentityServerConfigFactory
{
public static IEnumerable<Client> GetClients(string clientId, string secret, string redirectUri, string logoutRedirectUri)
public static IEnumerable<Client> GetClients(OpenIdConfig config)
{
yield return new Client
{
ClientId = clientId,
ClientName = "Proxy Client",
ClientId = config.ClientID,
ClientName = config.ClientName,
AllowedGrantTypes = GrantTypes.Code,
RequireConsent = false,
ClientSecrets =
{
new Secret(secret.Sha256())
new Secret(config.ClientSecret.Sha256())
},
// where to redirect to after login
RedirectUris = redirectUri.Split(",").Select(x => x.Trim()).ToArray(),
RedirectUris = config.RedirectUri.Split(",").Select(x => x.Trim()).ToArray(),
// where to redirect to after logout
PostLogoutRedirectUris = { logoutRedirectUri },
PostLogoutRedirectUris = { config.PostLogoutRedirectUri },
RequirePkce = false,
AllowedScopes = new List<string>
{

View file

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SteamOpenIdConnectProvider.Domains.IdentityServer
{
public class OpenIdConfig
{
public static readonly string Key = "OpenID";
public string ClientID { get; set; }
public string ClientSecret { get; set; }
public string RedirectUri { get; set; }
public string PostLogoutRedirectUri { get; set; }
public string ClientName { get; set; } = "Proxy Client";
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SteamOpenIdConnectProvider.Domains.Steam
{
public static class Constants
{
public static readonly string OpenIdUrl = "https://steamcommunity.com/openid/id/";
public static readonly string ApiUrl = "https://api.steampowered.com/";
public static readonly string GetPlayerSummariesUrl = ApiUrl + "ISteamUser/GetPlayerSummaries/v0002";
}
}

View file

@ -1,7 +1,8 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using SteamOpenIdConnectProvider.Profile.Models;
namespace SteamOpenIdConnectProvider.Profile.Models
namespace SteamOpenIdConnectProvider.Domains.Steam
{
public sealed class GetPlayerSummariesResponse
{

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace SteamOpenIdConnectProvider.Domains.Steam
{
public class SteamConfig
{
public static readonly string Key = "Steam";
public string ApplicationKey { get; internal set; }
}
}

View file

@ -8,39 +8,28 @@ using IdentityServer4.Extensions;
using IdentityServer4.Models;
using IdentityServer4.Services;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Configuration;
using SteamOpenIdConnectProvider.Profile.Models;
using Microsoft.Extensions.Options;
using SteamOpenIdConnectProvider.Domains.Steam;
using SteamOpenIdConnectProvider.Models.Steam;
namespace SteamOpenIdConnectProvider.Profile
namespace SteamOpenIdConnectProvider.Services
{
public class SteamProfileService : IProfileService
{
private readonly HttpClient _httpClient;
private readonly IConfiguration _configuration;
private readonly SteamConfig _config;
private readonly IUserClaimsPrincipalFactory<IdentityUser> _claimsFactory;
private readonly UserManager<IdentityUser> _userManager;
private async Task<GetPlayerSummariesResponse> GetPlayerSummariesAsync(IEnumerable<string> steamIds)
{
const string baseurl = "https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002";
var applicationKey = _configuration["Authentication:Steam:ApplicationKey"];
var url = $"{baseurl}/?key={applicationKey}&steamids={string.Join(',', steamIds)}";
var res = await _httpClient.GetStringAsync(url);
var response = JsonSerializer.Deserialize<SteamResponse<GetPlayerSummariesResponse>>(res);
return response.Response;
}
public SteamProfileService(
UserManager<IdentityUser> userManager,
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory,
IConfiguration configuration,
IOptions<SteamConfig> config,
HttpClient httpClient)
{
_userManager = userManager;
_claimsFactory = claimsFactory;
_configuration = configuration;
_config = config.Value;
_httpClient = httpClient;
}
@ -53,8 +42,7 @@ namespace SteamOpenIdConnectProvider.Profile
var claims = principal.Claims.ToList();
claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();
const string steamUrl = "https://steamcommunity.com/openid/id/";
var steamId = sub.Substring(steamUrl.Length);
var steamId = sub.Substring(Constants.OpenIdUrl.Length);
var userSummary = await GetPlayerSummariesAsync(new[] { steamId });
var player = userSummary.Players.FirstOrDefault();
@ -70,6 +58,13 @@ namespace SteamOpenIdConnectProvider.Profile
context.IssuedClaims = claims;
}
public async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
context.IsActive = user != null;
}
private void AddClaim(List<Claim> claims, string type, string value)
{
if (!string.IsNullOrEmpty(value))
@ -78,11 +73,12 @@ namespace SteamOpenIdConnectProvider.Profile
}
}
public async Task IsActiveAsync(IsActiveContext context)
private async Task<GetPlayerSummariesResponse> GetPlayerSummariesAsync(IEnumerable<string> steamIds)
{
var sub = context.Subject.GetSubjectId();
var user = await _userManager.FindByIdAsync(sub);
context.IsActive = user != null;
var url = $"{Constants.GetPlayerSummariesUrl}/?key={_config.ApplicationKey}&steamids={string.Join(',', steamIds)}";
var res = await _httpClient.GetStringAsync(url);
var response = JsonSerializer.Deserialize<SteamResponse<GetPlayerSummariesResponse>>(res);
return response.Response;
}
}
}

View file

@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
namespace SteamOpenIdConnectProvider.Profile.Models
namespace SteamOpenIdConnectProvider.Models.Steam
{
public sealed class SteamResponse<T>
{

View file

@ -12,8 +12,11 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using IdentityServer4.Services;
using Microsoft.AspNetCore.HttpOverrides;
using SteamOpenIdConnectProvider.Database;
using SteamOpenIdConnectProvider.Profile;
using SteamOpenIdConnectProvider.Services;
using SteamOpenIdConnectProvider.Models.IdentityServer;
using SteamOpenIdConnectProvider.Domains.Common;
using SteamOpenIdConnectProvider.Domains.IdentityServer;
using SteamOpenIdConnectProvider.Domains.Steam;
namespace SteamOpenIdConnectProvider
{
@ -31,7 +34,6 @@ namespace SteamOpenIdConnectProvider
services.AddControllers()
.SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddSingleton(Configuration);
services.AddDbContext<AppInMemoryDbContext>(options =>
options.UseInMemoryDatabase("default"));
@ -42,21 +44,21 @@ namespace SteamOpenIdConnectProvider
.AddEntityFrameworkStores<AppInMemoryDbContext>()
.AddDefaultTokenProviders();
var openIdConfig = Configuration.GetSection(OpenIdConfig.Key).Get<OpenIdConfig>();
services.AddIdentityServer(options =>
{
options.UserInteraction.LoginUrl = "/ExternalLogin";
})
.AddAspNetIdentity<IdentityUser>()
.AddInMemoryClients(IdentityServerConfig.GetClients(
Configuration["OpenID:ClientID"],
Configuration["OpenID:ClientSecret"],
Configuration["OpenID:RedirectUri"],
Configuration["OpenID:PostLogoutRedirectUri"]))
.AddInMemoryClients(IdentityServerConfigFactory.GetClients(openIdConfig))
.AddInMemoryPersistedGrants()
.AddDeveloperSigningCredential(true)
.AddInMemoryIdentityResources(IdentityServerConfig.GetIdentityResources());
.AddInMemoryIdentityResources(IdentityServerConfigFactory.GetIdentityResources());
services.AddHttpClient<IProfileService, SteamProfileService>();
var steamConfig = Configuration.GetSection(SteamConfig.Key).Get<SteamConfig>();
services
.Configure<SteamConfig>(Configuration.GetSection(SteamConfig.Key))
.AddHttpClient<IProfileService, SteamProfileService>();
services.AddAuthentication()
.AddCookie(options =>
@ -66,7 +68,7 @@ namespace SteamOpenIdConnectProvider
})
.AddSteam(options =>
{
options.ApplicationKey = Configuration["Authentication:Steam:ApplicationKey"];
options.ApplicationKey = steamConfig.ApplicationKey;
});
services.AddHealthChecks()
@ -80,18 +82,18 @@ namespace SteamOpenIdConnectProvider
app.UseDeveloperExceptionPage();
}
if (!string.IsNullOrEmpty(Configuration["Hosting:PathBase"]))
var hostingConfig = Configuration.GetSection(HostingConfig.Key).Get<HostingConfig>();
if (!string.IsNullOrEmpty(hostingConfig.BasePath))
{
app.UsePathBase(Configuration["Hosting:PathBase"]);
app.UsePathBase(hostingConfig.BasePath);
}
app.UseCookiePolicy();
app.Use(async (ctx, next) =>
{
var origin = Configuration["Hosting:PublicOrigin"];
if (!string.IsNullOrEmpty(origin))
if (!string.IsNullOrEmpty(hostingConfig.PublicOrigin))
{
ctx.SetIdentityServerOrigin(origin);
ctx.SetIdentityServerOrigin(hostingConfig.PublicOrigin);
}
await next();