Merge pull request #2695 from coreos-inc/oidc-internal-auth

OIDC internal auth support
This commit is contained in:
josephschorr 2017-10-02 16:51:17 -04:00 committed by GitHub
commit 3bef21253d
29 changed files with 341 additions and 38 deletions

View file

@ -622,21 +622,23 @@
<div class="co-panel-body">
<div class="description">
<p>
Authentication for the registry can be handled by either the registry itself, LDAP or external JWT endpoint.
Authentication for the registry can be handled by either the registry itself, LDAP, Keystone, OIDC or external JWT endpoint.
</p>
<p>
Additional <strong>external</strong> authentication providers (such as GitHub) can be used in addition for <strong>login into the UI</strong>.
</p>
</div>
<div class="co-alert co-alert-warning" ng-if="config.AUTHENTICATION_TYPE != 'Database' && !config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
It is <strong>highly recommended</strong> to require encrypted client passwords. External passwords used in the Docker client will be stored in <strong>plaintext</strong>!
<a ng-click="config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH = true">Enable this requirement now</a>.
</div>
<div ng-if="config.AUTHENTICATION_TYPE != 'OIDC'">
<div class="co-alert co-alert-warning" ng-if="config.AUTHENTICATION_TYPE != 'Database' && !config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
It is <strong>highly recommended</strong> to require encrypted client passwords. External passwords used in the Docker client will be stored in <strong>plaintext</strong>!
<a ng-click="config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH = true">Enable this requirement now</a>.
</div>
<div class="co-alert co-alert-success" ng-if="config.AUTHENTICATION_TYPE != 'Database' && config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
Note: The "Require Encrypted Client Passwords" feature is currently enabled which will
prevent passwords from being saved as plaintext by the Docker client.
<div class="co-alert co-alert-success" ng-if="config.AUTHENTICATION_TYPE != 'Database' && config.FEATURE_REQUIRE_ENCRYPTED_BASIC_AUTH">
Note: The "Require Encrypted Client Passwords" feature is currently enabled which will
prevent passwords from being saved as plaintext by the Docker client.
</div>
</div>
<table class="config-table" style="margin-bottom: 20px;">
@ -648,6 +650,7 @@
<option value="LDAP">LDAP</option>
<option value="Keystone">Keystone (OpenStack Identity)</option>
<option value="JWT">JWT Custom Authentication</option>
<option value="OIDC">OIDC Token Authentication</option>
</select>
</td>
</tr>
@ -687,6 +690,21 @@
</tr>
</table>
<!-- OIDC Token Authentication -->
<table class="config-table" ng-if="config.AUTHENTICATION_TYPE == 'OIDC'">
<tr>
<td>OIDC Provider:</td>
<td>
<select class="form-control" ng-model="config.INTERNAL_OIDC_SERVICE_ID" ng-if="getOIDCProviders(config).length">
<option value="{{ getOIDCProviderId(provider) }}" ng-repeat="provider in getOIDCProviders(config)">{{ config[provider]['SERVICE_NAME'] || getOIDCProviderId(provider) }}</option>
</select>
<div class="co-alert co-alert-danger" ng-if="!getOIDCProviders(config).length">
An OIDC provider must be configured to use this authentication system
</div>
</td>
</tr>
</table>
<!-- Keystone Authentication -->
<table class="config-table" ng-if="config.AUTHENTICATION_TYPE == 'Keystone'">
<tr>
@ -1073,7 +1091,7 @@
<span style="display: inline-block; margin-left: 10px">(<a href="javascript:void(0)" ng-click="removeOIDCProvider(provider)">Delete</a>)</span>
</div>
<div class="co-panel-body">
<div class="co-alert co-alert-warning" ng-if="config.AUTHENTICATION_TYPE != 'Database' && !(config[provider].LOGIN_BINDING_FIELD)">
<div class="co-alert co-alert-warning" ng-if="config.AUTHENTICATION_TYPE && config.AUTHENTICATION_TYPE != 'Database' && config.AUTHENTICATION_TYPE != 'OIDC' && !(config[provider].LOGIN_BINDING_FIELD)">
Warning: This OIDC provider is not bound to your <strong>{{ config.AUTHENTICATION_TYPE }}</strong> authentication. Logging in via this provider will create a <strong><span class="registry-name"></span>-only user</strong>, which is not the recommended approach. It is <strong>highly</strong> recommended to choose a "Binding Field" below.
</div>
@ -1134,7 +1152,7 @@
</div>
</td>
</tr>
<tr ng-if="config.AUTHENTICATION_TYPE != 'Database'">
<tr ng-if="config.AUTHENTICATION_TYPE != 'Database' && config.AUTHENTICATION_TYPE != 'OIDC'">
<td>Binding Field:</td>
<td>
<select class="form-control" ng-model="config[provider].LOGIN_BINDING_FIELD">
@ -1292,7 +1310,7 @@
</div>
<div class="co-panel-body">
<div class="description">
If enabled, users can submit Dockerfiles to be built and pushed by the Enterprise Registry.
If enabled, users can submit Dockerfiles to be built and pushed by <span class="registry-name"></span>.
</div>
<div class="config-bool-field" binding="config.FEATURE_BUILD_SUPPORT">

View file

@ -43,6 +43,10 @@ angular.module("core-config-setup", ['angularFileUpload'])
return config.AUTHENTICATION_TYPE == 'Keystone';
}, 'password': true},
{'id': 'oidc-auth', 'title': 'OIDC Authentication', 'condition': function(config) {
return config.AUTHENTICATION_TYPE == 'OIDC';
}},
{'id': 'signer', 'title': 'ACI Signing', 'condition': function(config) {
return config.FEATURE_ACI_CONVERSION;
}},
@ -203,7 +207,7 @@ angular.module("core-config-setup", ['angularFileUpload'])
return null;
}
return key.substr(0, index);
return key.substr(0, index).toLowerCase();
};
$scope.getOIDCProviders = function(config) {
@ -687,6 +691,12 @@ angular.module("core-config-setup", ['angularFileUpload'])
$scope.configform.$setValidity('storageConfig', valid);
};
$scope.$watch('config.INTERNAL_OIDC_SERVICE_ID', function(service_id) {
if (service_id) {
$scope.config['FEATURE_DIRECT_LOGIN'] = false;
}
});
$scope.$watch('config.FEATURE_STORAGE_REPLICATION', function() {
refreshStorageConfig();
});

View file

@ -21,7 +21,6 @@ angular.module('quay').directive('externalLoginButton', function () {
$scope.startSignin = function() {
$scope.signInStarted({'service': $scope.provider});
ExternalLoginService.getLoginUrl($scope.provider, $scope.action || 'login', function(url) {
// Save the redirect URL in a cookie so that we can redirect back after the service returns to us.
var redirectURL = $scope.redirectUrl || window.location.toString();
CookieService.putPermanent('quay.redirectAfterLoad', redirectURL);

View file

@ -237,11 +237,10 @@ import * as URI from 'urijs';
$scope.serializeDbUri = function(fields) {
if (!fields['server']) { return ''; }
if (!fields['database']) { return ''; }
var uri = URI();
try {
if (!fields['server']) { return ''; }
if (!fields['database']) { return ''; }
uri = uri && uri.host(fields['server']);
uri = uri && uri.protocol(fields['kind']);
uri = uri && uri.username(fields['username']);

View file

@ -13,6 +13,8 @@
function UserViewCtrl($scope, $routeParams, $timeout, ApiService, UserService, UIService, AvatarService, Config, ExternalLoginService) {
var username = $routeParams.username;
$scope.Config = Config;
$scope.showAppsCounter = 0;
$scope.showRobotsCounter = 0;
$scope.showBillingCounter = 0;
@ -25,7 +27,27 @@
$scope.hasSingleSignin = ExternalLoginService.hasSingleSignin();
$scope.context = {};
UserService.updateUserIn($scope);
$scope.oidcLoginProvider = null;
if (Config['INTERNAL_OIDC_SERVICE_ID']) {
ExternalLoginService.EXTERNAL_LOGINS.forEach(function(provider) {
if (provider.id == Config['INTERNAL_OIDC_SERVICE_ID']) {
$scope.oidcLoginProvider = provider;
}
});
}
UserService.updateUserIn($scope, function(user) {
if (user && user.username) {
if ($scope.oidcLoginProvider && $routeParams['idtoken']) {
$scope.context.idTokenCredentials = {
'username': UserService.getCLIUsername(),
'password': $routeParams['idtoken'],
'namespace': UserService.currentUser().username
};
}
}
});
var loadRepositories = function() {
var options = {

View file

@ -70,8 +70,25 @@
<!-- Settings -->
<cor-tab-pane id="settings">
<!-- OIDC Token -->
<div class="settings-section" ng-if="Config.AUTHENTICATION_TYPE == 'OIDC'">
<h3>Docker CLI Token</h3>
<div>
A generated token is <strong>required</strong> to login via the Docker CLI.
</div>
<table class="co-list-table" style="margin-top: 10px;">
<tr>
<td>CLI Token:</td>
<td>
<span class="external-login-button" is-link="true" action="cli" provider="oidcLoginProvider"></span>
</td>
</tr>
</table>
</div>
<!-- Encrypted Password -->
<div class="settings-section">
<div class="settings-section" ng-if="Config.AUTHENTICATION_TYPE != 'OIDC'">
<h3>Docker CLI Password</h3>
<div ng-if="!Features.REQUIRE_ENCRYPTED_BASIC_AUTH">
The Docker CLI stores passwords entered on the command line in <strong>plaintext</strong>. It is therefore highly recommended to generate an an encrypted version of your password to use for <code>docker login</code>.
@ -216,4 +233,7 @@
<!-- Credentials for encrypted passwords -->
<div class="credentials-dialog" credentials="context.encryptedPasswordCredentials" secret-title="Encrypted Password" entity-title="encrypted password" entity-icon="fa-key">
<!-- Credentials for ID token -->
<div class="credentials-dialog" credentials="context.idTokenCredentials" secret-title="CLI Token" entity-title="Docker CLI token" entity-icon="fa-key">
</div>