mirror of
https://github.com/bitwarden/server.git
synced 2025-02-16 01:51:21 +01:00
Test 1: add acr_values return validation value (#1285)
* Part 1: add acr_values return validation value * Update acr return value validation from OIDC specs * acr validation prompt clarification
This commit is contained in:
parent
1bd515e8f0
commit
17db94190e
@ -54,6 +54,7 @@ namespace Bit.Portal.Models
|
||||
AdditionalEmailClaimTypes = configurationData.AdditionalEmailClaimTypes;
|
||||
AdditionalNameClaimTypes = configurationData.AdditionalNameClaimTypes;
|
||||
AcrValues = configurationData.AcrValues;
|
||||
ExpectedReturnAcrValue = configurationData.ExpectedReturnAcrValue;
|
||||
}
|
||||
|
||||
[Required]
|
||||
@ -87,6 +88,8 @@ namespace Bit.Portal.Models
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
[Display(Name = "AcrValues")]
|
||||
public string AcrValues { get; set; }
|
||||
[Display(Name = "ExpectedReturnAcrValue")]
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 SP
|
||||
[Display(Name = "SpEntityId")]
|
||||
@ -238,6 +241,7 @@ namespace Bit.Portal.Models
|
||||
AdditionalEmailClaimTypes = AdditionalEmailClaimTypes,
|
||||
AdditionalNameClaimTypes = AdditionalNameClaimTypes,
|
||||
AcrValues = AcrValues,
|
||||
ExpectedReturnAcrValue = ExpectedReturnAcrValue,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -164,6 +164,12 @@
|
||||
<input asp-for="Data.AcrValues" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-7 form-group">
|
||||
<label asp-for="Data.ExpectedReturnAcrValue"></label>
|
||||
<input asp-for="Data.ExpectedReturnAcrValue" class="form-control">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -326,6 +326,16 @@ namespace Bit.Sso.Controllers
|
||||
|
||||
var externalUser = result.Principal;
|
||||
|
||||
// Validate acr claim against expectation before going further
|
||||
if (!string.IsNullOrWhiteSpace(ssoConfigData.ExpectedReturnAcrValue))
|
||||
{
|
||||
var acrClaim = externalUser.FindFirst(JwtClaimTypes.AuthenticationContextClassReference);
|
||||
if (acrClaim?.Value != ssoConfigData.ExpectedReturnAcrValue)
|
||||
{
|
||||
throw new Exception(_i18nService.T("AcrMissingOrInvalid"));
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the NameIdentifier used is not a transient name ID, if so, we need a different attribute
|
||||
// for the user identifier.
|
||||
static bool nameIdIsNotTransient(Claim c) => c.Type == ClaimTypes.NameIdentifier
|
||||
|
@ -333,19 +333,21 @@ namespace Bit.Core.Business.Sso
|
||||
{
|
||||
oidcOptions.Scope.AddIfNotExists(scope);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(config.ExpectedReturnAcrValue))
|
||||
{
|
||||
oidcOptions.Scope.AddIfNotExists(OpenIdConnectScopes.Acr);
|
||||
}
|
||||
|
||||
oidcOptions.StateDataFormat = new DistributedCacheStateDataFormatter(_httpContextAccessor, name);
|
||||
|
||||
// see: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest (acr_values)
|
||||
if (!string.IsNullOrWhiteSpace(config.AcrValues))
|
||||
{
|
||||
oidcOptions.Events = new OpenIdConnectEvents
|
||||
oidcOptions.Events ??= new OpenIdConnectEvents();
|
||||
oidcOptions.Events.OnRedirectToIdentityProvider = ctx =>
|
||||
{
|
||||
OnRedirectToIdentityProvider = ctx =>
|
||||
{
|
||||
ctx.ProtocolMessage.AcrValues = config.AcrValues;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
ctx.ProtocolMessage.AcrValues = config.AcrValues;
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,5 +49,16 @@
|
||||
/// not present (not logged in).
|
||||
/// </summary>
|
||||
public const string OfflineAccess = "offline_access";
|
||||
|
||||
/// <summary>
|
||||
/// OPTIONAL. Authentication Context Class Reference. String specifying
|
||||
/// an Authentication Context Class Reference value that identifies the
|
||||
/// Authentication Context Class that the authentication performed
|
||||
/// satisfied.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.2
|
||||
/// </remarks>
|
||||
public const string Acr = "acr";
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ namespace Bit.Core.Models.Data
|
||||
public string AdditionalEmailClaimTypes { get; set; }
|
||||
public string AdditionalNameClaimTypes { get; set; }
|
||||
public string AcrValues { get; set; }
|
||||
public string ExpectedReturnAcrValue { get; set; }
|
||||
|
||||
// SAML2 IDP
|
||||
public string IdpEntityId { get; set; }
|
||||
|
@ -638,10 +638,18 @@
|
||||
<value>Requested Authentication Context Class Reference values (acr_values)</value>
|
||||
<comment>'acr_values' is an explicit OIDC param, see https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="ExpectedReturnAcrValue" xml:space="preserve">
|
||||
<value>Expected "acr" Claim Value In Response (acr validation)</value>
|
||||
<comment>'acr' is an explicit OIDC claim type, see https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.2 (acr). It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="LoggedOutMessage" xml:space="preserve">
|
||||
<value>You have been logged out of the Bitwarden Business Portal.</value>
|
||||
</data>
|
||||
<data name="AccessDeniedError" xml:space="preserve">
|
||||
<value>Access Denied to this resource.</value>
|
||||
</data>
|
||||
<data name="AcrMissingOrInvalid" xml:space="preserve">
|
||||
<value>Expected authentication context class reference (acr) was not returned with the authentication response or is invalid.</value>
|
||||
<comment>'acr' is an explicit OIDC claim type, see https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.2 (acr). It should not be translated.</comment>
|
||||
</data>
|
||||
</root>
|
||||
|
Loading…
Reference in New Issue
Block a user