mirror of
https://github.com/bitwarden/server.git
synced 2024-11-29 13:25:17 +01:00
Added static client store (#899)
This commit is contained in:
parent
db7d05b52f
commit
38728143d8
79
src/Core/IdentityServer/ApiClient.cs
Normal file
79
src/Core/IdentityServer/ApiClient.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using IdentityServer4.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Bit.Core.IdentityServer
|
||||||
|
{
|
||||||
|
public class ApiClient : Client
|
||||||
|
{
|
||||||
|
public ApiClient(
|
||||||
|
GlobalSettings globalSettings,
|
||||||
|
string id,
|
||||||
|
int refreshTokenSlidingDays,
|
||||||
|
int accessTokenLifetimeHours,
|
||||||
|
string[] scopes = null)
|
||||||
|
{
|
||||||
|
ClientId = id;
|
||||||
|
AllowedGrantTypes = new[] { GrantType.ResourceOwnerPassword, GrantType.AuthorizationCode };
|
||||||
|
RefreshTokenExpiration = TokenExpiration.Sliding;
|
||||||
|
RefreshTokenUsage = TokenUsage.ReUse;
|
||||||
|
SlidingRefreshTokenLifetime = 86400 * refreshTokenSlidingDays;
|
||||||
|
AbsoluteRefreshTokenLifetime = 0; // forever
|
||||||
|
UpdateAccessTokenClaimsOnRefresh = true;
|
||||||
|
AccessTokenLifetime = 3600 * accessTokenLifetimeHours;
|
||||||
|
AllowOfflineAccess = true;
|
||||||
|
|
||||||
|
RequireConsent = false;
|
||||||
|
RequirePkce = true;
|
||||||
|
RequireClientSecret = false;
|
||||||
|
if (id == "web")
|
||||||
|
{
|
||||||
|
RedirectUris = new[] { $"{globalSettings.BaseServiceUri.Vault}/sso-connector.html" };
|
||||||
|
PostLogoutRedirectUris = new[] { globalSettings.BaseServiceUri.Vault };
|
||||||
|
AllowedCorsOrigins = new[] { globalSettings.BaseServiceUri.Vault };
|
||||||
|
}
|
||||||
|
else if (id == "desktop")
|
||||||
|
{
|
||||||
|
RedirectUris = new[] { "bitwarden://sso-callback" };
|
||||||
|
PostLogoutRedirectUris = new[] { "bitwarden://logged-out" };
|
||||||
|
}
|
||||||
|
else if (id == "connector")
|
||||||
|
{
|
||||||
|
var connectorUris = new List<string>();
|
||||||
|
for (var port = 8065; port <= 8070; port++)
|
||||||
|
{
|
||||||
|
connectorUris.Add(string.Format("http://localhost:{0}", port));
|
||||||
|
}
|
||||||
|
RedirectUris = connectorUris.Append("bwdc://sso-callback").ToList();
|
||||||
|
PostLogoutRedirectUris = connectorUris.Append("bwdc://logged-out").ToList();
|
||||||
|
}
|
||||||
|
else if (id == "browser")
|
||||||
|
{
|
||||||
|
RedirectUris = new[] { $"{globalSettings.BaseServiceUri.Vault}/sso-connector.html" };
|
||||||
|
PostLogoutRedirectUris = new[] { globalSettings.BaseServiceUri.Vault };
|
||||||
|
AllowedCorsOrigins = new[] { globalSettings.BaseServiceUri.Vault };
|
||||||
|
}
|
||||||
|
else if (id == "cli")
|
||||||
|
{
|
||||||
|
var cliUris = new List<string>();
|
||||||
|
for (var port = 8065; port <= 8070; port++)
|
||||||
|
{
|
||||||
|
cliUris.Add(string.Format("http://localhost:{0}", port));
|
||||||
|
}
|
||||||
|
RedirectUris = cliUris;
|
||||||
|
PostLogoutRedirectUris = cliUris;
|
||||||
|
}
|
||||||
|
else if (id == "mobile")
|
||||||
|
{
|
||||||
|
RedirectUris = new[] { "bitwarden://sso-callback" };
|
||||||
|
PostLogoutRedirectUris = new[] { "bitwarden://logged-out" };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scopes == null)
|
||||||
|
{
|
||||||
|
scopes = new string[] { "api" };
|
||||||
|
}
|
||||||
|
AllowedScopes = scopes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ using IdentityServer4.Models;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Claims;
|
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
|
|
||||||
@ -12,20 +11,21 @@ namespace Bit.Core.IdentityServer
|
|||||||
{
|
{
|
||||||
public class ClientStore : IClientStore
|
public class ClientStore : IClientStore
|
||||||
{
|
{
|
||||||
private static IDictionary<string, Client> _apiClients = StaticClients.GetApiClients();
|
|
||||||
|
|
||||||
private readonly IInstallationRepository _installationRepository;
|
private readonly IInstallationRepository _installationRepository;
|
||||||
private readonly IOrganizationRepository _organizationRepository;
|
private readonly IOrganizationRepository _organizationRepository;
|
||||||
private readonly GlobalSettings _globalSettings;
|
private readonly GlobalSettings _globalSettings;
|
||||||
|
private readonly StaticClientStore _staticClientStore;
|
||||||
|
|
||||||
public ClientStore(
|
public ClientStore(
|
||||||
IInstallationRepository installationRepository,
|
IInstallationRepository installationRepository,
|
||||||
IOrganizationRepository organizationRepository,
|
IOrganizationRepository organizationRepository,
|
||||||
GlobalSettings globalSettings)
|
GlobalSettings globalSettings,
|
||||||
|
StaticClientStore staticClientStore)
|
||||||
{
|
{
|
||||||
_installationRepository = installationRepository;
|
_installationRepository = installationRepository;
|
||||||
_organizationRepository = organizationRepository;
|
_organizationRepository = organizationRepository;
|
||||||
_globalSettings = globalSettings;
|
_globalSettings = globalSettings;
|
||||||
|
_staticClientStore = staticClientStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Client> FindClientByIdAsync(string clientId)
|
public async Task<Client> FindClientByIdAsync(string clientId)
|
||||||
@ -47,7 +47,10 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 24,
|
AccessTokenLifetime = 3600 * 24,
|
||||||
Enabled = installation.Enabled,
|
Enabled = installation.Enabled,
|
||||||
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, installation.Id.ToString()) }
|
Claims = new List<ClientClaim>
|
||||||
|
{
|
||||||
|
new ClientClaim(JwtClaimTypes.Subject, installation.Id.ToString())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +73,10 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 24,
|
AccessTokenLifetime = 3600 * 24,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, id) }
|
Claims = new List<ClientClaim>
|
||||||
|
{
|
||||||
|
new ClientClaim(JwtClaimTypes.Subject, id)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,13 +98,17 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 1,
|
AccessTokenLifetime = 3600 * 1,
|
||||||
Enabled = org.Enabled && org.UseApi,
|
Enabled = org.Enabled && org.UseApi,
|
||||||
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, org.Id.ToString()) }
|
Claims = new List<ClientClaim>
|
||||||
|
{
|
||||||
|
new ClientClaim(JwtClaimTypes.Subject, org.Id.ToString())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _apiClients.ContainsKey(clientId) ? _apiClients[clientId] : null;
|
return _staticClientStore.ApiClients.ContainsKey(clientId) ?
|
||||||
|
_staticClientStore.ApiClients[clientId] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
src/Core/IdentityServer/OidcIdentityClient.cs
Normal file
26
src/Core/IdentityServer/OidcIdentityClient.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using IdentityServer4;
|
||||||
|
using IdentityServer4.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Bit.Core.IdentityServer
|
||||||
|
{
|
||||||
|
public class OidcIdentityClient : Client
|
||||||
|
{
|
||||||
|
public OidcIdentityClient(GlobalSettings globalSettings)
|
||||||
|
{
|
||||||
|
ClientId = "oidc-identity";
|
||||||
|
RequireClientSecret = true;
|
||||||
|
RequirePkce = true;
|
||||||
|
ClientSecrets = new List<Secret> { new Secret(globalSettings.OidcIdentityClientKey.Sha256()) };
|
||||||
|
AllowedScopes = new string[]
|
||||||
|
{
|
||||||
|
IdentityServerConstants.StandardScopes.OpenId,
|
||||||
|
IdentityServerConstants.StandardScopes.Profile
|
||||||
|
};
|
||||||
|
AllowedGrantTypes = GrantTypes.Code;
|
||||||
|
Enabled = true;
|
||||||
|
RedirectUris = new List<string> { $"{globalSettings.BaseServiceUri.Identity}/signin-oidc" };
|
||||||
|
RequireConsent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/Core/IdentityServer/StaticClientStore.cs
Normal file
24
src/Core/IdentityServer/StaticClientStore.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using IdentityServer4.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Bit.Core.IdentityServer
|
||||||
|
{
|
||||||
|
public class StaticClientStore
|
||||||
|
{
|
||||||
|
public StaticClientStore(GlobalSettings globalSettings)
|
||||||
|
{
|
||||||
|
ApiClients = new List<Client>
|
||||||
|
{
|
||||||
|
new ApiClient(globalSettings, "mobile", 90, 1),
|
||||||
|
new ApiClient(globalSettings, "web", 30, 1),
|
||||||
|
new ApiClient(globalSettings, "browser", 30, 1),
|
||||||
|
new ApiClient(globalSettings, "desktop", 30, 1),
|
||||||
|
new ApiClient(globalSettings, "cli", 30, 1),
|
||||||
|
new ApiClient(globalSettings, "connector", 30, 24)
|
||||||
|
}.ToDictionary(c => c.ClientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<string, Client> ApiClients { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
@ -1,115 +0,0 @@
|
|||||||
using IdentityServer4;
|
|
||||||
using IdentityServer4.Models;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Bit.Core.IdentityServer
|
|
||||||
{
|
|
||||||
public class StaticClients
|
|
||||||
{
|
|
||||||
public static IDictionary<string, Client> GetApiClients()
|
|
||||||
{
|
|
||||||
return new List<Client>
|
|
||||||
{
|
|
||||||
new ApiClient("mobile", 90, 1),
|
|
||||||
new ApiClient("web", 30, 1),
|
|
||||||
new ApiClient("browser", 30, 1),
|
|
||||||
new ApiClient("desktop", 30, 1),
|
|
||||||
new ApiClient("cli", 30, 1),
|
|
||||||
new ApiClient("connector", 30, 24)
|
|
||||||
}.ToDictionary(c => c.ClientId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ApiClient : Client
|
|
||||||
{
|
|
||||||
public ApiClient(
|
|
||||||
string id,
|
|
||||||
int refreshTokenSlidingDays,
|
|
||||||
int accessTokenLifetimeHours,
|
|
||||||
string[] scopes = null)
|
|
||||||
{
|
|
||||||
ClientId = id;
|
|
||||||
AllowedGrantTypes = new[] { GrantType.ResourceOwnerPassword, GrantType.AuthorizationCode };
|
|
||||||
RefreshTokenExpiration = TokenExpiration.Sliding;
|
|
||||||
RefreshTokenUsage = TokenUsage.ReUse;
|
|
||||||
SlidingRefreshTokenLifetime = 86400 * refreshTokenSlidingDays;
|
|
||||||
AbsoluteRefreshTokenLifetime = 0; // forever
|
|
||||||
UpdateAccessTokenClaimsOnRefresh = true;
|
|
||||||
AccessTokenLifetime = 3600 * accessTokenLifetimeHours;
|
|
||||||
AllowOfflineAccess = true;
|
|
||||||
|
|
||||||
RequireConsent = false;
|
|
||||||
RequirePkce = true;
|
|
||||||
RequireClientSecret = false;
|
|
||||||
if (id == "web")
|
|
||||||
{
|
|
||||||
RedirectUris = new[] { "https://localhost:8080/sso-connector.html" };
|
|
||||||
PostLogoutRedirectUris = new[] { "https://localhost:8080" };
|
|
||||||
AllowedCorsOrigins = new[] { "https://localhost:8080" };
|
|
||||||
}
|
|
||||||
else if (id == "desktop")
|
|
||||||
{
|
|
||||||
RedirectUris = new[] { "bitwarden://sso-callback" };
|
|
||||||
PostLogoutRedirectUris = new[] { "bitwarden://logged-out" };
|
|
||||||
}
|
|
||||||
else if (id == "connector")
|
|
||||||
{
|
|
||||||
var connectorUris = new List<string>();
|
|
||||||
for (var port = 8065; port <= 8070; port++)
|
|
||||||
{
|
|
||||||
connectorUris.Add(string.Format("http://localhost:{0}", port));
|
|
||||||
}
|
|
||||||
RedirectUris = connectorUris.Append("bwdc://sso-callback").ToList();
|
|
||||||
PostLogoutRedirectUris = connectorUris.Append("bwdc://logged-out").ToList();
|
|
||||||
}
|
|
||||||
else if (id == "browser")
|
|
||||||
{
|
|
||||||
RedirectUris = new[] { "https://localhost:8080/sso-connector.html" };
|
|
||||||
PostLogoutRedirectUris = new[] { "https://localhost:8080" };
|
|
||||||
AllowedCorsOrigins = new[] { "https://localhost:8080" };
|
|
||||||
}
|
|
||||||
else if (id == "cli")
|
|
||||||
{
|
|
||||||
var cliUris = new List<string>();
|
|
||||||
for (var port = 8065; port <= 8070; port++)
|
|
||||||
{
|
|
||||||
cliUris.Add(string.Format("http://localhost:{0}", port));
|
|
||||||
}
|
|
||||||
RedirectUris = cliUris;
|
|
||||||
PostLogoutRedirectUris = cliUris;
|
|
||||||
}
|
|
||||||
else if (id == "mobile")
|
|
||||||
{
|
|
||||||
RedirectUris = new[] { "bitwarden://sso-callback" };
|
|
||||||
PostLogoutRedirectUris = new[] { "bitwarden://logged-out" };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scopes == null)
|
|
||||||
{
|
|
||||||
scopes = new string[] { "api" };
|
|
||||||
}
|
|
||||||
AllowedScopes = scopes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OidcIdentityClient : Client
|
|
||||||
{
|
|
||||||
public OidcIdentityClient(GlobalSettings globalSettings)
|
|
||||||
{
|
|
||||||
ClientId = "oidc-identity";
|
|
||||||
RequireClientSecret = true;
|
|
||||||
RequirePkce = true;
|
|
||||||
ClientSecrets = new List<Secret> { new Secret(globalSettings.OidcIdentityClientKey.Sha256()) };
|
|
||||||
AllowedScopes = new string[]
|
|
||||||
{
|
|
||||||
IdentityServerConstants.StandardScopes.OpenId,
|
|
||||||
IdentityServerConstants.StandardScopes.Profile
|
|
||||||
};
|
|
||||||
AllowedGrantTypes = GrantTypes.Code;
|
|
||||||
Enabled = true;
|
|
||||||
RedirectUris = new List<string> { $"{globalSettings.BaseServiceUri.Identity}/signin-oidc" };
|
|
||||||
RequireConsent = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -192,6 +192,7 @@ namespace Bit.Identity
|
|||||||
public static IIdentityServerBuilder AddCustomIdentityServerServices(IServiceCollection services,
|
public static IIdentityServerBuilder AddCustomIdentityServerServices(IServiceCollection services,
|
||||||
IWebHostEnvironment env, GlobalSettings globalSettings)
|
IWebHostEnvironment env, GlobalSettings globalSettings)
|
||||||
{
|
{
|
||||||
|
services.AddSingleton<StaticClientStore>();
|
||||||
services.AddTransient<IAuthorizationCodeStore, AuthorizationCodeStore>();
|
services.AddTransient<IAuthorizationCodeStore, AuthorizationCodeStore>();
|
||||||
|
|
||||||
var issuerUri = new Uri(globalSettings.BaseServiceUri.InternalIdentity);
|
var issuerUri = new Uri(globalSettings.BaseServiceUri.InternalIdentity);
|
||||||
|
Loading…
Reference in New Issue
Block a user