Hi, I have extended my previous patch for authentication with user certificate/smartcard. This patch includes patches and plugin described here: http://www.freeipa.org/page/V4/External_Authentication/Setup Page also contains steps to configure and test this feature. Once this patch is merged and released we will simplify this page to not confuse customers. Addressing ticket: https://fedorahosted.org/freeipa/ticket/5764
Thanks. -- Tibor Dudlák Intern - Identity management Special Projects Red Hat
From e22843f6ab1556528b307951fbcc2476a61a417f Mon Sep 17 00:00:00 2001 From: Tiboris <tibor.dud...@gmail.com> Date: Fri, 5 Aug 2016 11:47:06 +0200 Subject: [PATCH] Added support for authentication with user certificate https://fedorahosted.org/freeipa/ticket/5764 --- freeipa.spec.in | 5 + install/conf/ipa.conf | 14 +++ install/ui/src/freeipa/plugins/cert_auth.js | 179 ++++++++++++++++++++++++++++ ipaserver/plugins/xmlserver.py | 3 +- ipaserver/rpcserver.py | 5 + 5 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 install/ui/src/freeipa/plugins/cert_auth.js diff --git a/freeipa.spec.in b/freeipa.spec.in index 135e9c980011c6c2730c6c29a3c22098e48270d5..2b95b83613ca3720c95f255f7f64dc029195452c 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -817,6 +817,8 @@ install daemons/dnssec/ipa-ods-exporter %{buildroot}%{_libexecdir}/ipa/ipa-ods-e # Web UI plugin dir mkdir -p %{buildroot}%{_usr}/share/ipa/ui/js/plugins +mkdir -p %{buildroot}%{_usr}/share/ipa/ui/js/plugins-dist/cert_auth +install install/ui/src/freeipa/plugins/cert_auth.js %{buildroot}%{_usr}/share/ipa/ui/js/plugins-dist/cert_auth/cert_auth.js # DNSSEC config mkdir -p %{buildroot}%{_sysconfdir}/ipa/dnssec @@ -1210,6 +1212,9 @@ fi %{_usr}/share/ipa/ui/js/freeipa/app.js %{_usr}/share/ipa/ui/js/freeipa/core.js %dir %{_usr}/share/ipa/ui/js/plugins +%dir %{_usr}/share/ipa/ui/js/plugins-dist +%dir %{_usr}/share/ipa/ui/js/plugins-dist/cert_auth +%{_usr}/share/ipa/ui/js/plugins-dist/cert_auth/cert_auth.js %dir %{_usr}/share/ipa/ui/images %{_usr}/share/ipa/ui/images/*.jpg %{_usr}/share/ipa/ui/images/*.png diff --git a/install/conf/ipa.conf b/install/conf/ipa.conf index 3e7435903b2ad8c4ae5bfc48c0c9fca733757d5d..c37819ff2bd2c045404a383631435ad6c24fdaa3 100644 --- a/install/conf/ipa.conf +++ b/install/conf/ipa.conf @@ -77,6 +77,20 @@ WSGIScriptReloading Off Header always append Content-Security-Policy "frame-ancestors 'none'" </Location> +# Login with user certificate/smartcard configuration +<Location "/ipa/session/login_x509"> + AuthType none + GssapiCredStore keytab:/etc/httpd/conf/ipa.keytab + GssapiCredStore client_keytab:/etc/httpd/conf/ipa.keytab + GssapiDelegCcacheDir /var/run/httpd/ipa/clientcaches + GssapiImpersonate On + NSSVerifyClient require + NSSUserName SSL_CLIENT_CERT + LookupUserByCertificate On + WSGIProcessGroup ipa + WSGIApplicationGroup ipa +</Location> + # Turn off Apache authentication for sessions <Location "/ipa/session/json"> Satisfy Any diff --git a/install/ui/src/freeipa/plugins/cert_auth.js b/install/ui/src/freeipa/plugins/cert_auth.js new file mode 100644 index 0000000000000000000000000000000000000000..282883d6fe82258405afb167dd61b5d6b0f1a7bd --- /dev/null +++ b/install/ui/src/freeipa/plugins/cert_auth.js @@ -0,0 +1,179 @@ +/* Authors: + * Petr Vobornik <pvobo...@redhat.com> + * Tibor Dudlák <tdud...@redhat.com> + * + * Copyright (C) 2016 Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +/* + Plugin to add a button with aside text to FreeiPA login screen + + Tested against FreeIPA 4.4 + + Limitation: only one such plugin can be installed - one can override + functionality of the other + */ + +// we can also depend on other plugin +define([ + 'dojo/Deferred', + 'dojo/dom-construct', + 'dojo/_base/declare', + 'freeipa/jquery', + 'freeipa/_base/Spec_mod', + 'freeipa/ipa', + 'freeipa/auth', + 'freeipa/phases', + 'freeipa/reg', + 'freeipa/plugins/login', + 'freeipa/widgets/LoginScreen', + ], + function(Deferred, construct, declare, $, SpecMod, IPA, auth, phases, + reg, mod_login, LoginScreen) { + + +var exp = {}; // module object (export) + +exp.CustomLoginScreen = declare([LoginScreen], { + + crtauth_btn_node: null, + + auth_failed: "Authentication with personal certificate failed", + + msg: "<p><i class=\"fa fa-info-circle\"></i> To login with <strong>Smart Card</strong>," + + "please make sure you have valid personal certificate. </p>", + + login_url: '/ipa/session/login_x509', + + render_buttons: function(container) { + // add button node to DOM + this.crtauth_btn_node = IPA.button({ + name: 'crtauth', + title:"Login using personal certificate", + label: "Smart Card Login", + button_class: 'btn btn-link', + click: this.crt_login.bind(this) + })[0]; + + // similar to jquery.append(node, container) + construct.place(this.crtauth_btn_node, container); + construct.place(document.createTextNode(" "), container); + + // call base class method to create other buttons + this.inherited(arguments); + }, + + crt_login: function() { + // add custom auth login here + this.lookup_credentials().then(function(status) { + if (status === 200) { + this.emit('logged_in'); + } else { + var val_summary = this.get_widget('validation'); + val_summary.add_error('login', this.auth_failed); + } + }.bind(this)); + }, + + lookup_credentials: function() { + var status; + var d = new Deferred(); + + function error_handler(xhr, text_status, error_thrown) { + d.resolve(xhr.status); + IPA.hide_activity_icon(); + } + + function success_handler(data, text_status, xhr) { + auth.current.set_authenticated(true, 'kerberos'); + d.resolve(xhr.status); + IPA.hide_activity_icon(); + } + + var request = { + url: this.login_url, + cache: false, + type: "GET", + success: success_handler, + error: error_handler + }; + IPA.display_activity_icon(); + $.ajax(request); + + return d.promise; + }, + + show_login_view: function() { + + this.inherited(arguments); + // make sure that crtauth button is also shown when switching from sync form + // a bit of hack because, we need to use the exact buttons which were defined + // in original LoginScreen -> does't scale if some button is added in later + // versions + this.set_visible_buttons(['crtauth', 'sync', 'login']); + }, + + set_login_aside_text: function() { + // allow to set aside text (the text on right side with help text) + + // generate original + this.inherited(arguments); + + // add own + var aside = this.aside; + aside += this.msg; + this.set('aside', aside); + + //alternative solution: + // $(this.aside_node).append($("<p/>", { text: "My text"})); + } +}); + + +exp.replace_login_screen_spec = function(entity) { + + var mod = new SpecMod(); + + var diff = { + $replace: [ + [ + 'widgets', + [[{ name: 'login_screen'}, + { + $type: 'custom_login_screen', + name: 'login_screen' + }]] + ] + ] + }; + mod.mod(mod_login.facet_spec, diff); +}; + +exp.override = function() { + + exp.replace_login_screen_spec(); +}; + +exp.register = function() { + var w = reg.widget; + w.register('custom_login_screen', exp.CustomLoginScreen ); +}; + +phases.on('registration', exp.register); +phases.on('customization', exp.override); + +return exp; +}); diff --git a/ipaserver/plugins/xmlserver.py b/ipaserver/plugins/xmlserver.py index d8fe24e0cb407603e9898e934229c9373f3c8b62..1843c0568543951f2c817616d9e988deaab47056 100644 --- a/ipaserver/plugins/xmlserver.py +++ b/ipaserver/plugins/xmlserver.py @@ -28,12 +28,13 @@ register = Registry() if api.env.context in ('server', 'lite'): - from ipaserver.rpcserver import wsgi_dispatch, xmlserver, jsonserver_kerb, jsonserver_session, login_kerberos, login_password, change_password, sync_token, xmlserver_session + from ipaserver.rpcserver import wsgi_dispatch, xmlserver, jsonserver_kerb, jsonserver_session, login_kerberos, login_x509, login_password, change_password, sync_token, xmlserver_session register()(wsgi_dispatch) register()(xmlserver) register()(jsonserver_kerb) register()(jsonserver_session) register()(login_kerberos) + register()(login_x509) register()(login_password) register()(change_password) register()(sync_token) diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py index d036f3c27521f17709672b830d5aa58167c76b34..a181ecfcb1d01b1c2dd5ee6cb9721d69be8c1863 100644 --- a/ipaserver/rpcserver.py +++ b/ipaserver/rpcserver.py @@ -876,6 +876,11 @@ class login_kerberos(Backend, KerberosSession, HTTP_Status): return self.finalize_kerberos_acquisition('login_kerberos', user_ccache_name, environ, start_response) + +class login_x509(login_kerberos, KerberosSession, HTTP_Status): + key = '/session/login_x509' + + class login_password(Backend, KerberosSession, HTTP_Status): content_type = 'text/plain' -- 2.7.4
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code