mirror of
https://github.com/bitwarden/web
synced 2025-12-06 00:03:28 +00:00
364 lines
18 KiB
HTML
364 lines
18 KiB
HTML
<div class="page-header d-flex">
|
|
<h1>{{'singleSignOn' | i18n}}</h1>
|
|
</div>
|
|
|
|
<ng-container *ngIf="loading">
|
|
<i class="fa fa-spinner fa-spin text-muted" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
|
<span class="sr-only">{{'loading' | i18n}}</span>
|
|
</ng-container>
|
|
|
|
<form #form (ngSubmit)="submit()" [formGroup]="data" [appApiAction]="formPromise" *ngIf="!loading" ngNativeValidate>
|
|
<p>
|
|
{{'ssoPolicyHelpStart' | i18n}}
|
|
<a routerLink="../policies">{{'ssoPolicyHelpLink' | i18n}}</a>
|
|
{{'ssoPolicyHelpEnd' | i18n}}
|
|
<br>
|
|
{{'ssoPolicyHelpKeyConnector' | i18n}}
|
|
</p>
|
|
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="enabled" [formControl]="enabled" name="Enabled">
|
|
<label class="form-check-label" for="enabled">{{'allowSso' | i18n}}</label>
|
|
</div>
|
|
<small class="form-text text-muted">{{'allowSsoDesc' | i18n}}</small>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>{{'memberDecryptionOption' | i18n}}</label>
|
|
<div class="form-check form-check-block">
|
|
<input class="form-check-input" type="radio" id="memberDecryptionPass" [value]="false" formControlName="keyConnectorEnabled">
|
|
<label class="form-check-label" for="memberDecryptionPass">
|
|
{{'masterPass' | i18n}}
|
|
<small>{{'memberDecryptionPassDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
<div class="form-check mt-2 form-check-block">
|
|
<input class="form-check-input" type="radio" id="memberDecryptionKey" [value]="true" formControlName="keyConnectorEnabled"
|
|
[attr.disabled]="!organization.useKeyConnector || null">
|
|
<label class="form-check-label" for="memberDecryptionKey">
|
|
{{'keyConnector' | i18n}}
|
|
<a target="_blank" rel="noopener" appA11yTitle="{{'learnMore' | i18n}}"
|
|
href="https://bitwarden.com/help/article/about-key-connector/">
|
|
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
|
|
</a>
|
|
<small>{{'memberDecryptionKeyConnectorDesc' | i18n}}</small>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<ng-container *ngIf="data.value.keyConnectorEnabled">
|
|
<app-callout type="warning" [useAlertRole]="true">
|
|
{{'keyConnectorWarning' | i18n}}
|
|
</app-callout>
|
|
|
|
<div class="form-group">
|
|
<label for="keyConnectorUrl">{{'keyConnectorUrl' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" formControlName="keyConnectorUrl" id="keyConnectorUrl" required>
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary" (click)="validateKeyConnectorUrl()"
|
|
[disabled]="!enableTestKeyConnector">
|
|
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"
|
|
*ngIf="keyConnectorUrl.pending"></i>
|
|
<span *ngIf="!keyConnectorUrl.pending">
|
|
{{'keyConnectorTest' | i18n}}
|
|
</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<ng-container *ngIf="keyConnectorUrl.pristine && !keyConnectorUrl.pending">
|
|
<div class="text-danger" *ngIf="keyConnectorUrl.hasError('invalidUrl')" role="alert">
|
|
<i class="fa fa-exclamation-circle" aria-hidden="true"></i>
|
|
{{'keyConnectorTestFail' | i18n}}
|
|
</div>
|
|
<div class="text-success" *ngIf="!keyConnectorUrl.hasError('invalidUrl')" role="alert">
|
|
<i class="fa fa-check-circle-o" aria-hidden="true"></i>
|
|
{{'keyConnectorTestSuccess' | i18n}}
|
|
</div>
|
|
</ng-container>
|
|
</div>
|
|
</ng-container>
|
|
|
|
<div class="form-group">
|
|
<label for="type">{{'type' | i18n}}</label>
|
|
<select class="form-control" id="type" formControlName="configType">
|
|
<option value="0" disabled>{{'selectType' | i18n}}</option>
|
|
<option value="1">OpenID Connect</option>
|
|
<option value="2">SAML 2.0</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- OIDC -->
|
|
<div *ngIf="data.value.configType == 1">
|
|
<div class="config-section">
|
|
<h2>{{'openIdConnectConfig' | i18n}}</h2>
|
|
<div class="form-group">
|
|
<label>{{'callbackPath' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" readonly [value]="callbackPath">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'copyValue' | i18n}}"
|
|
(click)="copy(callbackPath)">
|
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>{{'signedOutCallbackPath' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" readonly [value]="signedOutCallbackPath">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'copyValue' | i18n}}"
|
|
(click)="copy(signedOutCallbackPath)">
|
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="authority">{{'authority' | i18n}}</label>
|
|
<input class="form-control" formControlName="authority" id="authority">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="clientId">{{'clientId' | i18n}}</label>
|
|
<input class="form-control" formControlName="clientId" id="clientId">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="clientSecret">{{'clientSecret' | i18n}}</label>
|
|
<input class="form-control" formControlName="clientSecret" id="clientSecret">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="metadataAddress">{{'metadataAddress' | i18n}}</label>
|
|
<input class="form-control" formControlName="metadataAddress" id="metadataAddress">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="redirectBehavior">{{'oidcRedirectBehavior' | i18n}}</label>
|
|
<select class="form-control" formControlName="redirectBehavior" id="redirectBehavior">
|
|
<option value="0">Redirect GET</option>
|
|
<option value="1">Form POST</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="getClaimsFromUserInfoEndpoint"
|
|
formControlName="getClaimsFromUserInfoEndpoint">
|
|
<label class="form-check-label" for="getClaimsFromUserInfoEndpoint">
|
|
{{'getClaimsFromUserInfoEndpoint' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="additionalScopes">{{'additionalScopes' | i18n}}</label>
|
|
<input class="form-control" formControlName="additionalScopes" id="additionalScopes">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="additionalUserIdClaimTypes">{{'additionalUserIdClaimTypes' | i18n}}</label>
|
|
<input class="form-control" formControlName="additionalUserIdClaimTypes"
|
|
id="additionalUserIdClaimTypes">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="additionalEmailClaimTypes">{{'additionalEmailClaimTypes' | i18n}}</label>
|
|
<input class="form-control" formControlName="additionalEmailClaimTypes"
|
|
id="additionalEmailClaimTypes">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="additionalNameClaimTypes">{{'additionalNameClaimTypes' | i18n}}</label>
|
|
<input class="form-control" formControlName="additionalNameClaimTypes"
|
|
id="additionalNameClaimTypes">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="acrValues">{{'acrValues' | i18n}}</label>
|
|
<input class="form-control" formControlName="acrValues" id="acrValues">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="expectedReturnAcrValue">{{'expectedReturnAcrValue' | i18n}}</label>
|
|
<input class="form-control" formControlName="expectedReturnAcrValue" id="expectedReturnAcrValue">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div *ngIf="data.value.configType == 2">
|
|
<!-- SAML2 SP -->
|
|
<div class="config-section">
|
|
<h2>{{'samlSpConfig' | i18n}}</h2>
|
|
<div class="form-group">
|
|
<label>{{'spEntityId' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" readonly [value]="spEntityId" >
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'copyValue' | i18n}}"
|
|
(click)="copy(spEntityId)">
|
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>{{'spMetadataUrl' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" readonly [value]="spMetadataUrl">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'launch' | i18n}}"
|
|
(click)="launchUri(spMetadataUrl)">
|
|
<i class="fa fa-lg fa-external-link" aria-hidden="true"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'copyValue' | i18n}}"
|
|
(click)="copy(spMetadataUrl)">
|
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>{{'spAcsUrl' | i18n}}</label>
|
|
<div class="input-group">
|
|
<input class="form-control" readonly [value]="spAcsUrl">
|
|
<div class="input-group-append">
|
|
<button type="button" class="btn btn-outline-secondary"
|
|
appA11yTitle="{{'copyValue' | i18n}}"
|
|
(click)="copy(spAcsUrl)">
|
|
<i class="fa fa-lg fa-clone" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="spNameIdFormat">{{'spNameIdFormat' | i18n}}</label>
|
|
<select class="form-control" formControlName="spNameIdFormat" id="spNameIdFormat">
|
|
<option value="0">Not Configured</option>
|
|
<option value="1">Unspecified</option>
|
|
<option value="2">Email Address</option>
|
|
<option value="3">X.509 Subject Name</option>
|
|
<option value="4">Windows Domain Qualified Name</option>
|
|
<option value="5">Kerberos Principal Name</option>
|
|
<option value="6">Entity Identifier</option>
|
|
<option value="7">Persistent</option>
|
|
<option value="8">Transient</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="spOutboundSigningAlgorithm">{{'spOutboundSigningAlgorithm' | i18n}}</label>
|
|
<select class="form-control" formControlName="spOutboundSigningAlgorithm"
|
|
id="spOutboundSigningAlgorithm">
|
|
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="spSigningBehavior">{{'spSigningBehavior' | i18n}}</label>
|
|
<select class="form-control" formControlName="spSigningBehavior" id="spSigningBehavior">
|
|
<option value="0">If IdP Wants Authn Requests Signed</option>
|
|
<option value="1">Always</option>
|
|
<option value="3">Never</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="spMinIncomingSigningAlgorithm">{{'spMinIncomingSigningAlgorithm' | i18n}}</label>
|
|
<select class="form-control" formControlName="spMinIncomingSigningAlgorithm"
|
|
id="spMinIncomingSigningAlgorithm">
|
|
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="spWantAssertionsSigned"
|
|
formControlName="spWantAssertionsSigned">
|
|
<label class="form-check-label" for="spWantAssertionsSigned">
|
|
{{'spWantAssertionsSigned' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="spValidateCertificates"
|
|
formControlName="spValidateCertificates">
|
|
<label class="form-check-label" for="spValidateCertificates">
|
|
{{'spValidateCertificates' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SAML2 IDP -->
|
|
<div class="config-section">
|
|
<h2>{{'samlIdpConfig' | i18n}}</h2>
|
|
|
|
<div class="form-group">
|
|
<label for="idpEntityId">{{'idpEntityId' | i18n}}</label>
|
|
<input class="form-control" formControlName="idpEntityId" id="idpEntityId">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpBindingType">{{'idpBindingType' | i18n}}</label>
|
|
<select class="form-control" formControlName="idpBindingType" id="idpBindingType">
|
|
<option value="1">Redirect</option>
|
|
<option value="2">HTTP POST</option>
|
|
<option value="4">Artifact</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpSingleSignOnServiceUrl">{{'idpSingleSignOnServiceUrl' | i18n}}</label>
|
|
<input class="form-control" formControlName="idpSingleSignOnServiceUrl" id="idpSingleSignOnServiceUrl">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpSingleLogoutServiceUrl">{{'idpSingleLogoutServiceUrl' | i18n}}</label>
|
|
<input class="form-control" formControlName="idpSingleLogoutServiceUrl" id="idpSingleLogoutServiceUrl">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpArtifactResolutionServiceUrl">{{'idpArtifactResolutionServiceUrl' | i18n}}</label>
|
|
<input class="form-control" formControlName="idpArtifactResolutionServiceUrl"
|
|
id="idpArtifactResolutionServiceUrl">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpX509PublicCert">{{'idpX509PublicCert' | i18n}}</label>
|
|
<textarea formControlName="idpX509PublicCert" class="form-control form-control-sm text-monospace"
|
|
rows="6" id="idpX509PublicCert"></textarea>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="idpOutboundSigningAlgorithm">{{'idpOutboundSigningAlgorithm' | i18n}}</label>
|
|
<select class="form-control" formControlName="idpOutboundSigningAlgorithm"
|
|
id="idpOutboundSigningAlgorithm">
|
|
<option *ngFor="let o of samlSigningAlgorithms" [ngValue]="o">{{o}}</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="idpAllowUnsolicitedAuthnResponse"
|
|
formControlName="idpAllowUnsolicitedAuthnResponse">
|
|
<label class="form-check-label" for="idpAllowUnsolicitedAuthnResponse">
|
|
{{'idpAllowUnsolicitedAuthnResponse' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="idpDisableOutboundLogoutRequests"
|
|
formControlName="idpDisableOutboundLogoutRequests">
|
|
<label class="form-check-label" for="idpDisableOutboundLogoutRequests">
|
|
{{'idpDisableOutboundLogoutRequests' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="idpWantAuthnRequestsSigned"
|
|
formControlName="idpWantAuthnRequestsSigned">
|
|
<label class="form-check-label" for="idpWantAuthnRequestsSigned">
|
|
{{'idpWantAuthnRequestsSigned' | i18n}}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-submit" [disabled]="form.loading">
|
|
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
|
|
<span>{{'save' | i18n}}</span>
|
|
</button>
|
|
</form>
|