Merge branch 'v2.0'
This commit is contained in:
commit
4bc3933b7e
|
@ -55,7 +55,7 @@ To integrate a Web application in LL::NG, you have the following
|
|||
possibilities:
|
||||
|
||||
- Protect the application with the Handler, and push user identity
|
||||
trough HTTP headers. This is how main Access Manager products, like
|
||||
through HTTP headers. This is how main Access Manager products, like
|
||||
CA SiteMinder, are working. This also how Apache authentication
|
||||
modules are working, so if your application is compatible with Apache
|
||||
authentication (often called "external authentifcation"), then you
|
||||
|
|
|
@ -11,7 +11,7 @@ Presentation
|
|||
Since 4.0 release, it offers an easy way to configure SSO thanks to
|
||||
authentication subsystems.
|
||||
|
||||
Authentication against LL::NG can be done trough:
|
||||
Authentication against LL::NG can be done through:
|
||||
|
||||
- HTTP headers (LL::NG Handler)
|
||||
- SAML 2 (LL::NG as SAML2 IDP)
|
||||
|
|
|
@ -28,7 +28,7 @@ Little effort is required to translate the encoded string back into the
|
|||
user name and password, and many popular security tools will decode the
|
||||
strings "on the fly".
|
||||
|
||||
So HTTP Basic Authentication is managed trough an HTTP header
|
||||
So HTTP Basic Authentication is managed through an HTTP header
|
||||
(``Authorization``), that can be forged by LL::NG, with this
|
||||
precautions:
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ We suppose you configured LemonLDAP::NG as
|
|||
as Service Provider.
|
||||
|
||||
In LL::NG Manager, create an new SP and load simpleSAMLphp metadata
|
||||
trough URL (by default:
|
||||
through URL (by default:
|
||||
http://localhost/simplesamlphp/module.php/saml/sp/metadata.php/default-sp):
|
||||
|
||||
|image1|
|
||||
|
|
|
@ -20,7 +20,7 @@ Configuration
|
|||
You can find all suitable information here:
|
||||
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/preauth.html
|
||||
|
||||
To summarize, to get the user connected trough the ``Auth-User`` HTTP
|
||||
To summarize, to get the user connected through the ``Auth-User`` HTTP
|
||||
Header, use this Sping Security configuration:
|
||||
|
||||
.. code-block:: xml
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Wiki.js
|
||||
=====
|
||||
=======
|
||||
|
||||
|image0|
|
||||
|
||||
|
@ -14,7 +14,7 @@ complete presentation.
|
|||
It feature an OpenID Connect login that work with LemonLDAP::NG.
|
||||
|
||||
Configuring Wiki.js
|
||||
-----------------
|
||||
-------------------
|
||||
|
||||
Connect to your wiki.js instance with an Admin user, in the admin panel, go to "Authentication".
|
||||
|
||||
|
@ -45,7 +45,7 @@ with the following parameters (Options -> Basic) :
|
|||
* **Allowed redirection addresses for login**: The "Callback URL" defined in wiki.js.
|
||||
|
||||
\_Portal with internal CA
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. danger::
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ User Roles Settings
|
|||
You can assign WP Roles depending on values sent by CAS.
|
||||
|
||||
The rules syntax is quite special, you can use it or you can just define
|
||||
macros on LL::NG side and send them trough CAS to keep simple rules on
|
||||
macros on LL::NG side and send them through CAS to keep simple rules on
|
||||
WP side.
|
||||
|
||||
For example create a macro ``role_wordpress_admin`` which contains ``1``
|
||||
|
|
|
@ -25,7 +25,7 @@ session under the form:
|
|||
|
||||
``_casPT<serviceID>`` = **Proxy ticket value**
|
||||
|
||||
They can then be forwarded to applications trough
|
||||
They can then be forwarded to applications through
|
||||
:ref:`HTTP headers<headers>`.
|
||||
|
||||
.. tip::
|
||||
|
|
|
@ -17,8 +17,8 @@ Presentation
|
|||
stacks. It is described here: http://openid.net/connect/.
|
||||
|
||||
LL::NG can act as an OpenID Connect Relying Party (RP) towards multiple
|
||||
OpenID Connect Providers (OP). It will get the user identity trough an
|
||||
ID Token, and grab user attributes trough UserInfo endpoint.
|
||||
OpenID Connect Providers (OP). It will get the user identity through an
|
||||
ID Token, and grab user attributes through UserInfo endpoint.
|
||||
|
||||
As an RP, LL::NG supports a lot of OpenID Connect features:
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ https://developers.google.com/identity/protocols/OpenIDConnect
|
|||
|
||||
.. attention::
|
||||
|
||||
Google does not support logout trough OpenID Connect. If
|
||||
Google does not support logout through OpenID Connect. If
|
||||
you close your session on LL::NG side, your Google session will still be
|
||||
open.
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Presentation
|
|||
be rejected).
|
||||
- The portal of the secondary LL::NG structure is configured to
|
||||
delegate authentication to a remote portal. A request to the main
|
||||
session database is done (trough
|
||||
session database is done (through
|
||||
:doc:`SOAP session backend<soapsessionbackend>`) to be sure that the
|
||||
session exists.
|
||||
- If ``exportedAttr`` is set, only those attributes are copied in the
|
||||
|
|
|
@ -19,7 +19,7 @@ modules to access it.
|
|||
:ref:`here<start-configuration-database>`.
|
||||
|
||||
By default, configuration is stored in :doc:`files<fileconfbackend>`, so
|
||||
access trough network is not possible. To allow this, use
|
||||
access through network is not possible. To allow this, use
|
||||
:doc:`SOAP<soapconfbackend>` for configuration access, or use a network
|
||||
service like :doc:`SQL database<sqlconfbackend>` or
|
||||
:doc:`LDAP directory<ldapconfbackend>`.
|
||||
|
@ -46,7 +46,7 @@ For example, to configure the ``File`` configuration backend:
|
|||
Manager
|
||||
-------
|
||||
|
||||
Most of configuration can be done trough LemonLDAP::NG Manager (by
|
||||
Most of configuration can be done through LemonLDAP::NG Manager (by
|
||||
default http://manager.example.com).
|
||||
|
||||
By default, Manager is protected to allow only the demonstration user
|
||||
|
|
|
@ -11,8 +11,8 @@ Presentation
|
|||
stacks. It is described here: http://openid.net/connect/.
|
||||
|
||||
LL::NG can act as an OpenID Connect Provider (OP). It will answer to
|
||||
OpenID Connect requests to give user identity (trough ID Token) and
|
||||
information (trough User Info end point).
|
||||
OpenID Connect requests to give user identity (through ID Token) and
|
||||
information (through User Info end point).
|
||||
|
||||
As an OP, LL::NG supports a lot of OpenID Connect features:
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ For each attribute, you can set:
|
|||
- **Mandatory**: if set to "On", then this attribute is required to
|
||||
build the SAML response, an error will displayed if there is no value
|
||||
for it. Optional attribute will be sent only if there is a value
|
||||
associated. Else it just will be sent trough an attribute response,
|
||||
associated. Else it just will be sent through an attribute response,
|
||||
if explicitly requested in an attribute request.
|
||||
- **Format**: optional, SAML attribute format.
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ You can close the Kerberos session:
|
|||
|
||||
kdestroy
|
||||
|
||||
Now you can compare the above result with the same request done trough
|
||||
Now you can compare the above result with the same request done through
|
||||
the keytab file:
|
||||
|
||||
::
|
||||
|
|
|
@ -4,7 +4,7 @@ Logout forward
|
|||
Presentation
|
||||
------------
|
||||
|
||||
Even if LL:NG can catch logout URL trough
|
||||
Even if LL:NG can catch logout URL through
|
||||
:ref:`virtual host rules<rules>`, you can have the
|
||||
need to forward a logout to other applications, to close their local
|
||||
sessions.
|
||||
|
|
|
@ -89,7 +89,7 @@ Save the configuration and exit the Manager.
|
|||
|
||||
.. tip::
|
||||
|
||||
The next time you will access Manager, it will be trough
|
||||
The next time you will access Manager, it will be through
|
||||
LL::NG.
|
||||
|
||||
Enable protection on Manager, by editing ``lemonldap-ng.ini``:
|
||||
|
|
|
@ -10,7 +10,7 @@ This Handler is able to check an OAuth2 access token to retrieve the
|
|||
user real session and protect a virtual host like a standard Handler
|
||||
(access control and HTTP headers transmission).
|
||||
|
||||
This requires to get an OAuth2 access token trough LL::NG Portal (OpenID
|
||||
This requires to get an OAuth2 access token through LL::NG Portal (OpenID
|
||||
Connect server). This access token can then be used in the
|
||||
``Authorization`` header to authenticate to the Web Service / API
|
||||
protected by the OAuth2 Handler.
|
||||
|
|
|
@ -64,7 +64,7 @@ Dynamic Registration
|
|||
|
||||
If dynamic registration is enabled, you can configure the following
|
||||
options to define attributes and extra claims when a new relying party
|
||||
is registered trough the ``/oauth2/register`` endpoint:
|
||||
is registered through the ``/oauth2/register`` endpoint:
|
||||
|
||||
- Exported vars for dynamic registration
|
||||
- Extra claims for dynamic registration
|
||||
|
|
|
@ -273,7 +273,7 @@ log4perlConfFile Log4Perl logger configur
|
|||
logLevel Log level, must be set in .ini ✔ ✔ ✔ ✔
|
||||
logger technical logger ✔ ✔ ✔ ✔
|
||||
loginHistoryEnabled Enable login history ✔
|
||||
logoutServices Send logout trough GET request to these services ✔
|
||||
logoutServices Send logout through GET request to these services ✔
|
||||
lwpOpts Options given to LWP::UserAgent ✔
|
||||
lwpSslOpts SSL options given to LWP::UserAgent ✔
|
||||
macros Macros ✔
|
||||
|
|
|
@ -20,13 +20,13 @@ LemonLDAP::NG portal menu has 4 modules:
|
|||
- **OIDC Consents**: display user's OpenId Connect consents
|
||||
- **Logout**: logout button
|
||||
|
||||
Each module can be activated trough a rule, using user session
|
||||
information. These rules can be set trough Manager:
|
||||
Each module can be activated through a rule, using user session
|
||||
information. These rules can be set through Manager:
|
||||
``General Parameters`` > ``Portal`` > ``Menu`` > ``Modules activation``.
|
||||
|
||||
You can use ``0`` or ``1`` to disable/enable the module, or use a more
|
||||
complex rule. For example, to display the password change form only for
|
||||
user authenticated trough LDAP or DBI:
|
||||
user authenticated through LDAP or DBI:
|
||||
|
||||
.. code-block:: perl
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ Configuration
|
|||
-------------
|
||||
|
||||
- **SOAP/REST exported attributes**: list session attributes shared
|
||||
trough SOAP/REST
|
||||
through SOAP/REST
|
||||
|
||||
- Use ``+`` to append to the default list of technical attributes,
|
||||
- Use ``+`` to append the default list of technical attributes,
|
||||
example: ``+ uid mail``
|
||||
|
||||
REST
|
||||
|
|
|
@ -2,7 +2,7 @@ InWebo Second Factor
|
|||
====================
|
||||
|
||||
`InWebo <https://www.inwebo.com/>`_ is a proprietary MFA solution.
|
||||
You can use is as second factor trough :doc:`Radius 2FA module<radius2f>`.
|
||||
You can use is as second factor through :doc:`Radius 2FA module<radius2f>`.
|
||||
|
||||
Configuration
|
||||
~~~~~~~~~~~~~
|
||||
|
|
|
@ -39,7 +39,7 @@ Handler use the default Apache error code for the following cases:
|
|||
- An error occurs on server side: SERVER_ERROR (500)
|
||||
- The application is in maintenance: HTTP_SERVICE_UNAVAILABLE (503)
|
||||
|
||||
These errors can be catch trough Apache ``ErrorDocument`` directive or
|
||||
These errors can be catch through Apache ``ErrorDocument`` directive or
|
||||
Nginx ``error_page`` directive, to redirect user on a specific page:
|
||||
|
||||
.. code-block:: apache
|
||||
|
|
|
@ -33,7 +33,7 @@ protected with a firewall that only accepts HTTP flows.
|
|||
Most of the time, REST session backend is used by Handlers installed on
|
||||
external servers.
|
||||
|
||||
To configure it, REST session backend will be set trough Manager in
|
||||
To configure it, REST session backend will be set through Manager in
|
||||
global configuration (used by all Handlers), and the real session
|
||||
backend will be configured for local components in lemonldap-ng.ini.
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ protected with a firewall that only accepts HTTP flows.
|
|||
Most of the time, SOAP session backend is used by Handlers installed on
|
||||
external servers.
|
||||
|
||||
To configure it, SOAP session backend will be set trough Manager in
|
||||
To configure it, SOAP session backend will be set through Manager in
|
||||
global configuration (used by all Hanlders), and the real session
|
||||
backend will be configured for local components in lemonldap-ng.ini.
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ OpenID
|
|||
================ =============================================
|
||||
Key Description
|
||||
================ =============================================
|
||||
\_openid\_\ *id* Consent to share attribute *id* trough OpenID
|
||||
\_openid\_\ *id* Consent to share attribute *id* through OpenID
|
||||
================ =============================================
|
||||
|
||||
OpenID Connect
|
||||
|
|
|
@ -78,14 +78,13 @@ has configStorage => (
|
|||
$_[0]->{p}->HANDLER->localConfig->{configStorage};
|
||||
}
|
||||
);
|
||||
|
||||
has exportedAttr => (
|
||||
is => 'rw',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $conf = $_[0]->{conf};
|
||||
if ( $conf->{exportedAttr} and $conf->{exportedAttr} !~ /^\s*\+/ ) {
|
||||
return [ split /\s+/, $conf->{exportedAttr} ];
|
||||
return '[' . join( ',', split /\s+/, $conf->{exportedAttr} ) . ']';
|
||||
}
|
||||
else {
|
||||
my @attributes = (
|
||||
|
@ -97,14 +96,17 @@ has exportedAttr => (
|
|||
if ( my $exportedAttr = $conf->{exportedAttr} ) {
|
||||
$exportedAttr =~ s/^\s*\+\s+//;
|
||||
@attributes = ( @attributes, split( /\s+/, $exportedAttr ) );
|
||||
|
||||
# Convert @attributes into hash to remove duplicates
|
||||
my %attributes = map( { $_ => 1 } @attributes );
|
||||
return '[' . join( ',', keys %attributes ) . ']';
|
||||
}
|
||||
|
||||
# convert @attributes into hash to remove duplicates
|
||||
# Convert @attributes into hash to remove duplicates
|
||||
my %attributes = map( { $_ => 1 } @attributes );
|
||||
%attributes =
|
||||
( %attributes, %{ $conf->{exportedVars} }, %{ $conf->{macros} },
|
||||
);
|
||||
|
||||
return '[' . join( ',', keys %attributes ) . ']';
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +249,7 @@ sub init {
|
|||
);
|
||||
extends @parents if ($add);
|
||||
$self->setTypes( $self->conf ) if ( $self->conf->{restSessionServer} );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -326,9 +329,8 @@ sub newAuthSession {
|
|||
$self->logger->debug(
|
||||
"REST authentication result for $req->{user}: code $req->{error}");
|
||||
|
||||
if ( $req->error > 0 ) {
|
||||
return $self->p->sendError( $req, 'Bad credentials', 401 );
|
||||
}
|
||||
return $self->p->sendError( $req, 'Bad credentials', 401 )
|
||||
if ( $req->error > 0 );
|
||||
return $self->session( $req, $id );
|
||||
}
|
||||
|
||||
|
@ -368,11 +370,13 @@ sub delSession {
|
|||
$self->logger->debug("REST request to delete session $id");
|
||||
my $res = $self->p->_deleteSession( $req, $session );
|
||||
$self->logger->debug(" Result is $res");
|
||||
|
||||
return $self->p->sendJSONresponse( $req, { result => $res } );
|
||||
}
|
||||
|
||||
sub delMySession {
|
||||
my ( $self, $req, $id ) = @_;
|
||||
|
||||
return $self->delSession( $req, $req->userData->{_session_id} );
|
||||
}
|
||||
|
||||
|
@ -380,10 +384,9 @@ sub mysession {
|
|||
my ( $self, $req ) = @_;
|
||||
|
||||
# 1. whoami
|
||||
if ( defined $req->param('whoami') ) {
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
{ result => $req->userData->{ $self->conf->{whatToTrace} } } );
|
||||
}
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
{ result => $req->userData->{ $self->conf->{whatToTrace} } } )
|
||||
if defined $req->param('whoami');
|
||||
|
||||
if ( defined $req->param('gettoken') ) {
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
|
@ -416,6 +419,7 @@ sub mysession {
|
|||
$self->logger->debug(" Result is $res");
|
||||
return $self->p->sendJSONresponse( $req, { result => $res } );
|
||||
}
|
||||
|
||||
return $self->p->sendError( $req,
|
||||
'whoami or authorizationfor is required', 400 );
|
||||
}
|
||||
|
@ -423,7 +427,18 @@ sub mysession {
|
|||
sub getMyKey {
|
||||
my ( $self, $req, $key ) = @_;
|
||||
$key ||= '';
|
||||
$self->logger->debug("Request to get personal session info -> Key : $key");
|
||||
if ($key) {
|
||||
$self->logger->debug(
|
||||
"Request to get personal session info -> Key: $key");
|
||||
}
|
||||
else {
|
||||
my $keys = $self->exportedAttr;
|
||||
$keys =~ s/(?:\[|\])//g;
|
||||
$keys =~ s/,/, /g;
|
||||
$self->logger->debug(
|
||||
"Request to get exported attributes -> Keys: $keys");
|
||||
}
|
||||
|
||||
return $self->session(
|
||||
$req,
|
||||
$req->userData->{_session_id},
|
||||
|
@ -435,6 +450,7 @@ sub updateMySession {
|
|||
my ( $self, $req ) = @_;
|
||||
my $res = 0;
|
||||
my $mKeys = [];
|
||||
|
||||
if ( my $token = $req->param('token') ) {
|
||||
if ( $self->ott->getToken($token) ) {
|
||||
if ( $req->param('sessionType') eq 'persistent' ) {
|
||||
|
@ -469,9 +485,8 @@ sub updateMySession {
|
|||
else {
|
||||
$self->logger->error('Update session request without token');
|
||||
}
|
||||
unless ($res) {
|
||||
return $self->p->sendError( $req, 'Modification refused', 403 );
|
||||
}
|
||||
|
||||
return $self->p->sendError( $req, 'Modification refused', 403 ) unless $res;
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
{ result => 1, count => $res, modifiedKeys => $mKeys } );
|
||||
}
|
||||
|
@ -482,6 +497,7 @@ sub delKeyInMySession {
|
|||
my $mKeys = [];
|
||||
my $dkey = $req->param('key');
|
||||
my $sub = $req->param('sub');
|
||||
|
||||
if ( my $token = $req->param('token') ) {
|
||||
if ( $self->ott->getToken($token) ) {
|
||||
if ( $req->param('sessionType') eq 'persistent' ) {
|
||||
|
@ -554,9 +570,8 @@ sub delKeyInMySession {
|
|||
else {
|
||||
$self->logger->error('Update session request without token');
|
||||
}
|
||||
unless ($res) {
|
||||
return $self->p->sendError( $req, 'Modification refused', 403 );
|
||||
}
|
||||
|
||||
return $self->p->sendError( $req, 'Modification refused', 403 ) unless $res;
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
{ result => 1, count => $res, modifiedKeys => $dkey } );
|
||||
}
|
||||
|
@ -765,8 +780,8 @@ sub _checkSecret {
|
|||
$self->logger->error('Bad key, force denied');
|
||||
}
|
||||
}
|
||||
return $isValid;
|
||||
|
||||
return $isValid;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -26,7 +26,6 @@ extends qw(
|
|||
);
|
||||
|
||||
has server => ( is => 'rw' );
|
||||
|
||||
has configStorage => (
|
||||
is => 'ro',
|
||||
lazy => 1,
|
||||
|
@ -34,7 +33,6 @@ has configStorage => (
|
|||
$_[0]->{p}->HANDLER->localConfig->{configStorage};
|
||||
}
|
||||
);
|
||||
|
||||
has exportedAttr => (
|
||||
is => 'rw',
|
||||
lazy => 1,
|
||||
|
@ -53,9 +51,13 @@ has exportedAttr => (
|
|||
if ( my $exportedAttr = $conf->{exportedAttr} ) {
|
||||
$exportedAttr =~ s/^\s*\+\s+//;
|
||||
@attributes = ( @attributes, split( /\s+/, $exportedAttr ) );
|
||||
|
||||
# Convert @attributes into hash to remove duplicates
|
||||
my %attributes = map( { $_ => 1 } @attributes );
|
||||
return '[' . join( ',', keys %attributes ) . ']';
|
||||
}
|
||||
|
||||
# convert @attributes into hash to remove duplicates
|
||||
# Convert @attributes into hash to remove duplicates
|
||||
my %attributes = map( { $_ => 1 } @attributes );
|
||||
%attributes =
|
||||
( %attributes, %{ $conf->{exportedVars} }, %{ $conf->{macros} },
|
||||
|
|
|
@ -21,6 +21,7 @@ my $client = LLNG::Manager::Test->new( {
|
|||
'$uid eq "msmith"' => '=5',
|
||||
},
|
||||
restSessionServer => 1,
|
||||
exportedAttr => '+ mail uid _session_id'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -46,8 +47,11 @@ ok(
|
|||
count(1);
|
||||
$json = expectJSON($res);
|
||||
|
||||
ok( $json->{uid} eq 'dwho', 'uid found' ) or explain( $json, "uid='dwho'" );
|
||||
ok( $json->{authenticationLevel} == 3, 'Authentication level upgraded' );
|
||||
count(1);
|
||||
ok( scalar keys %$json == 10, 'Ten exported attributes found' )
|
||||
or explain( $json, 'Ten exported attributes' );
|
||||
count(3);
|
||||
|
||||
ok( $client->logout($id), 'Logout' );
|
||||
count(1);
|
||||
|
|
Loading…
Reference in New Issue