mirror of
https://github.com/bitwarden/server.git
synced 2024-11-22 12:15:36 +01:00
Add SAML 2.0 metadata export for dynamic SPs (#1094)
This commit is contained in:
parent
bc1a20101a
commit
85edc03461
@ -31,6 +31,7 @@ namespace Bit.Portal.Models
|
|||||||
RedirectBehavior = configurationData.RedirectBehavior;
|
RedirectBehavior = configurationData.RedirectBehavior;
|
||||||
GetClaimsFromUserInfoEndpoint = configurationData.GetClaimsFromUserInfoEndpoint;
|
GetClaimsFromUserInfoEndpoint = configurationData.GetClaimsFromUserInfoEndpoint;
|
||||||
SpEntityId = configurationData.BuildSaml2ModulePath(globalSettings.BaseServiceUri.Sso);
|
SpEntityId = configurationData.BuildSaml2ModulePath(globalSettings.BaseServiceUri.Sso);
|
||||||
|
SpMetadataUrl = configurationData.BuildSaml2MetadataUrl(globalSettings.BaseServiceUri.Sso, organizationId.ToString());
|
||||||
SpAcsUrl = configurationData.BuildSaml2AcsUrl(globalSettings.BaseServiceUri.Sso, organizationId.ToString());
|
SpAcsUrl = configurationData.BuildSaml2AcsUrl(globalSettings.BaseServiceUri.Sso, organizationId.ToString());
|
||||||
IdpEntityId = configurationData.IdpEntityId;
|
IdpEntityId = configurationData.IdpEntityId;
|
||||||
IdpBindingType = configurationData.IdpBindingType;
|
IdpBindingType = configurationData.IdpBindingType;
|
||||||
@ -75,6 +76,8 @@ namespace Bit.Portal.Models
|
|||||||
// SAML2 SP
|
// SAML2 SP
|
||||||
[Display(Name = "SpEntityId")]
|
[Display(Name = "SpEntityId")]
|
||||||
public string SpEntityId { get; set; }
|
public string SpEntityId { get; set; }
|
||||||
|
[Display(Name = "SpMetadataUrl")]
|
||||||
|
public string SpMetadataUrl { get; set; }
|
||||||
[Display(Name = "SpAcsUrl")]
|
[Display(Name = "SpAcsUrl")]
|
||||||
public string SpAcsUrl { get; set; }
|
public string SpAcsUrl { get; set; }
|
||||||
[Display(Name = "NameIdFormat")]
|
[Display(Name = "NameIdFormat")]
|
||||||
|
@ -156,6 +156,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-7 form-group">
|
||||||
|
<label asp-for="Data.SpMetadataUrl">@i18nService.T("SpMetadataUrl")</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input asp-for="Data.SpMetadataUrl" class="form-control" readonly>
|
||||||
|
<div class="input-group-append">
|
||||||
|
<a class="btn btn-outline-secondary launch-button"
|
||||||
|
href="@Model.Data.SpMetadataUrl"
|
||||||
|
target="_blank"
|
||||||
|
aria-label="@i18nService.T("LaunchSpMetadataUrl")" title="@i18nService.T("LaunchSpMetadataUrl")"
|
||||||
|
tabindex="-1">
|
||||||
|
<i class="fa fa-lg fa-external-link" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<button type="button" class="btn btn-outline-secondary copy-button"
|
||||||
|
aria-label="@i18nService.T("CopySpMetadataUrl")" title="@i18nService.T("CopySpMetadataUrl")"
|
||||||
|
tabindex="-1">
|
||||||
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-7 form-group">
|
<div class="col-7 form-group">
|
||||||
<label asp-for="Data.SpAcsUrl">@i18nService.T("SpAcsUrl")</label>
|
<label asp-for="Data.SpAcsUrl">@i18nService.T("SpAcsUrl")</label>
|
||||||
|
72
bitwarden_license/src/Sso/Controllers/MetadataController.cs
Normal file
72
bitwarden_license/src/Sso/Controllers/MetadataController.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Sso.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Sustainsys.Saml2.AspNetCore2;
|
||||||
|
using Sustainsys.Saml2.WebSso;
|
||||||
|
|
||||||
|
namespace Bit.Sso.Controllers
|
||||||
|
{
|
||||||
|
public class MetadataController : Controller
|
||||||
|
{
|
||||||
|
private readonly IAuthenticationSchemeProvider _schemeProvider;
|
||||||
|
|
||||||
|
public MetadataController(
|
||||||
|
IAuthenticationSchemeProvider schemeProvider)
|
||||||
|
{
|
||||||
|
_schemeProvider = schemeProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("saml2/{scheme}")]
|
||||||
|
public async Task<IActionResult> ViewAsync(string scheme)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(scheme))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var authScheme = await _schemeProvider.GetSchemeAsync(scheme);
|
||||||
|
if (authScheme == null ||
|
||||||
|
!(authScheme is DynamicAuthenticationScheme dynamicAuthScheme) ||
|
||||||
|
dynamicAuthScheme?.SsoType != SsoType.Saml2)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dynamicAuthScheme.Options is Saml2Options options))
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var uri = new Uri(
|
||||||
|
Request.Scheme
|
||||||
|
+ "://"
|
||||||
|
+ Request.Host
|
||||||
|
+ Request.Path
|
||||||
|
+ Request.QueryString);
|
||||||
|
|
||||||
|
var pathBase = Request.PathBase.Value;
|
||||||
|
pathBase = string.IsNullOrEmpty(pathBase) ? "/" : pathBase;
|
||||||
|
|
||||||
|
var requestdata = new HttpRequestData(
|
||||||
|
Request.Method,
|
||||||
|
uri,
|
||||||
|
pathBase,
|
||||||
|
null,
|
||||||
|
Request.Cookies,
|
||||||
|
(data) => data);
|
||||||
|
|
||||||
|
var metadataResult = CommandFactory
|
||||||
|
.GetCommand(CommandFactory.MetadataCommand)
|
||||||
|
.Run(requestdata, options);
|
||||||
|
//Response.Headers.Add("Content-Disposition", $"filename= bitwarden-saml2-meta-{scheme}.xml");
|
||||||
|
return new ContentResult
|
||||||
|
{
|
||||||
|
Content = metadataResult.Content,
|
||||||
|
ContentType = "text/xml",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,6 +62,11 @@ namespace Bit.Core.Models.Data
|
|||||||
return string.Concat(BuildSaml2ModulePath(ssoUri, scheme), "/Acs");
|
return string.Concat(BuildSaml2ModulePath(ssoUri, scheme), "/Acs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string BuildSaml2MetadataUrl(string ssoUri = null, string scheme = null)
|
||||||
|
{
|
||||||
|
return BuildSaml2ModulePath(ssoUri, scheme);
|
||||||
|
}
|
||||||
|
|
||||||
private string BuildSsoUrl(string relativePath, string ssoUri)
|
private string BuildSsoUrl(string relativePath, string ssoUri)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(ssoUri) ||
|
if (string.IsNullOrWhiteSpace(ssoUri) ||
|
||||||
|
@ -265,6 +265,9 @@
|
|||||||
<data name="SpEntityId" xml:space="preserve">
|
<data name="SpEntityId" xml:space="preserve">
|
||||||
<value>SP Entity ID</value>
|
<value>SP Entity ID</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SpMetadataUrl" xml:space="preserve">
|
||||||
|
<value>SAML 2.0 Metadata URL</value>
|
||||||
|
</data>
|
||||||
<data name="SpAcsUrl" xml:space="preserve">
|
<data name="SpAcsUrl" xml:space="preserve">
|
||||||
<value>Assertion Consumer Service (ACS) URL</value>
|
<value>Assertion Consumer Service (ACS) URL</value>
|
||||||
</data>
|
</data>
|
||||||
@ -475,6 +478,12 @@
|
|||||||
<data name="CopySpEntityId">
|
<data name="CopySpEntityId">
|
||||||
<value>Copy the SP Entity Id to your clipboard</value>
|
<value>Copy the SP Entity Id to your clipboard</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CopySpMetadataUrl">
|
||||||
|
<value>Copy the SAML 2.0 Metadata URL to your clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="LaunchSpMetadataUrl">
|
||||||
|
<value>View the SAML 2.0 Metadata (opens in a new window)</value>
|
||||||
|
</data>
|
||||||
<data name="CopySpAcsUrl">
|
<data name="CopySpAcsUrl">
|
||||||
<value>Copy the Assertion Consumer Service (ACS) URL to your clipboard</value>
|
<value>Copy the Assertion Consumer Service (ACS) URL to your clipboard</value>
|
||||||
</data>
|
</data>
|
||||||
|
Loading…
Reference in New Issue
Block a user