Security Configuration

Once you have configured Lenses, it’s time to set up security.

Security has two important parts: authentication and authorization. Authentication is how users login to Lenses whereas authorization governs the rules of what a user can and can not do. Starting with Lenses 3.0, authorization is configured within the Lenses user interface instead of the security configuration file.

The platform supports a cascading set of authentication modules.

Every authentication module that is configured in the security configuration file, is enabled automatically. Since the Lenses Administrator and Basic modules do not require any configuration, they are always active.

Lenses Administrator

A default account with administrator privileges is always active. The default credentials are admin / admin and if left at default, a notification will show in the user interface, informing that the setup is insecure.

The default account username and password may be adjusted as below. For security purposes it is strongly advised to use your password’s SHA256 checksum instead of the plaintext.

# Lenses Administrator settings

lenses.security.user = "admin"

## For the password you can either use the plaintext
#lenses.security.password = "admin"
## Or you may use the SHA256 checksum (advised)
lenses.security.password = "sha256:8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"

To create a SHA256 checksum for your password you can use the command line tools available in your Linux server or macOS.

unset HISTFILE # Disable history for the current terminal
echo -n "password" | sha256sum

Note

To disable the Lenses Administrator user, please set an adequately long random password. You can achieve this by using the snippet below:

dd if=/dev/urandom count=1 bs=1024 | sha256sum

Basic

In BASIC mode user accounts are managed by Lenses. Once a user successfully logs in, he is linked to one or more groups and therefore inherits all the permissions attached to the groups he belongs to.

To add, manage and delete users for the basic authentication module visit the Admin section in the Lenses web interface. You will need an account with sufficient privileges to manage users. Alternatively you can add users via the command-line, using the Lenses CLI tool.

The internal database is stored on-disk, under the lenses.storage.directory. Please keep this directory intact between updates and upgrades.

Password rules

To enforce specific password rules the following configurations need to be set

# The regex to check the password. If it does not meet the requirements adding a user account or changing the
# password will be rejected.
lenses.security.basic.password.rules.regex = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{6,20})"

# Human readable description for the password rule. This will be returned to the user when the requirements fail
lenses.security.basic.password.rules.desc = "Password needs to contain: one lower case, one upper case, 1 number, one special character, and have a length of 6 to 20 characters"

LDAP

For this mode, Lenses relies on the LDAP server to handle the user authentication. The groups that a user belongs to (authorization) may come either from LDAP (automatic mapping), or via manually mapping an LDAP user to a set of Lenses groups.

Since the authentication is deferred, this means users are stored by LDAP and not Lenses. Once the authentication is successful, the next step involves querying LDAP for the user’s groups. All the user’s groups are then matched by name (case sensitive) with the groups stored in Lenses. All the matching groups’ permissions are combined. If a user has been assigned manually a set of Lenses groups, then the groups coming from LDAP are ignored.

Active Directory (AD) and OpenLDAP (with the memberOf overlay if LDAP group mapping is required) servers are tested and supported in general. Due to the LDAP standard ambiguity, it is impossible to support all the configurations in the wild. The most usual pain point is LDAP group mapping. If the default class that extracts and maps LDAP groups to Lenses groups does not work, it is possible to implement your own.

Before setting up an LDAP connection, we advise to familiarize with LDAP and/or have access to your LDAP and/or Active Directory administrators.

An LDAP setup example with LDAP group mapping is shown below:

# LDAP connection details

lenses.security.ldap.url="ldaps://example.com:636"
## For the LDAP user please use the distinguished name (DN).
## The LDAP user must be able to list users and their groups.
lenses.security.ldap.user="cn=lenses,ou=Services,dc=example,dc=com"
lenses.security.ldap.password="[PASSWORD]"
## When set to true, it uses the lenses.security.ldap.user to read the user's groups
## lenses.security.ldap.use.service.user.search=false

# LDAP user search settings

lenses.security.ldap.base="ou=Users,dc=example,dc=com"
lenses.security.ldap.filter="(&(objectClass=person)(sAMAccountName=<user>))"

# LDAP group search and mapping settings

lenses.security.ldap.plugin.class="io.lenses.security.ldap.LdapMemberOfUserGroupPlugin"
lenses.security.ldap.plugin.group.extract.regex="(?i)CN=(\\w+),ou=Groups.*"
lenses.security.ldap.plugin.memberof.key="memberOf"
lenses.security.ldap.plugin.person.name.key = "sn"

In the example above you can distinguish three key sections for LDAP:

  • the connection settings,
  • the user search settings,
  • and the group search settings.

Each key is explained in detail at the LDAP Configuration Options Table.

Lenses uses the connection settings to connect to your LDAP server. The provided account should be able to list users under the base path and their groups. The default group plugin only needs access to the memberOf attributes for each user, but your custom implementation may need different permissions.

When a user tries to login, a query is sent to the LDAP server for all accounts that are under the lenses.security.ldap.base and match the lenses.security.ldap.filter. The result needs to be unique; a distinguished name (DN) —the user that will login to Lenses.

In the example, the application would query the LDAP server for all entities under ou=Users,dc=example,dc=com that satisfy the LDAP filter (&(objectClass=person)(sAMAccountName=<user>)) where <user> would be replaced by the username that tries to login to Lenses. A more simple filter could be cn=<user>, which for user Mark would return the DN cn=Mark,ou=Users,dc=example,dc=com.

Once the user has been verified, Lenses queries the user groups and maps them to Lenses groups. For every LDAP group that matches a Lenses group, the user is granted the selected permissions. This process is done by the security_ldap_group_extract_plugin. Depending on the LDAP setup, only one of the user or the Lenses service user may be able to retrieve the group memberships. This can be controlled by the option lenses.security.ldap.use.service.user.search. The default value (false) uses the user itself to query for groups. Groups be can created in the admin section of the web interface, or in the command line via the lenses-cli application.

There are those LDAP setups with stricter security levels which do not allow for a logged user to list his own groups. In this case the user account set via lenses.security.ldap.user can be used to list the groups for any logged users. Of course that account needs elevated privileges to do so. To enable this behavior set lenses.security.ldap.use.service.user.search to true.

Warning

Set lenses.security.ldap.use.service.user.search to true to use lenses.security.ldap.user account to list a logged user groups when your LDAP setup restricts most of the users action to list their groups.

LDAP Manual Group Mapping

In some cases mapping LDAP groups to Lenses groups is not desired. It is possible to map manually an LDAP user to a set of Lenses groups, using the web interface, or the lenses-cli. In such scenario, you create a user of type LDAP inside Lenses and assign them groups. Authentication is still handled via LDAP but all LDAP groups for this user are ignored. To learn more about permissions in Lenses, see the _user_management section.

When you create an LDAP user in Lenses, the username will be used in the search expression set in lenses.security.ldap.filter to authenticate them.

If no user should be allowed to use the groups coming from LDAP, then this functionality should be disabled. Whilst it cannot be disabled explicitly, you may set lenses.security.ldap.plugin.memberof.key or lenses.security.ldap.plugin.group.extract.regex to a bogus entry, rendering it unusable. An example would be:

lenses.security.ldap.plugin.memberof.key = "notaKey"

Group Extract Plugin

The group extract plugin is a class that implements an LDAP query that retrieves a user’s groups and makes any necessary transformation to match the LDAP group to a Lenses group name.

The default class implementation that comes with Lenses is io.lenses.security.ldap.LdapMemberOfUserGroupPlugin. If your LDAP server supports the memberOf functionality, where each user has his/her group memberships added as attributes to his/her entity, you can use it by setting the lenses.security.ldap.plugin.class option to this class:

lenses.security.ldap.plugin.class=io.lenses.security.ldap.LdapMemberOfUserGroupPlugin

The configuration settings for the default group extract plugin can be found at the LDAP Configuration Options Table. Below you will see a brief example of its setup.

# Set the full classpath that implements the group extraction
lenses.security.ldap.plugin.class="io.lenses.security.ldap.LdapMemberOfUserGroupPlugin"

# The plugin uses the 'memberOf' attribute. If this attribute has a different
# name in your LDAP set it here.
lenses.security.ldap.plugin.memberof.key="memberOf"

# This regular expression should return the group common name. If it matches
# a Lenses group name, the user is granted its permissions.
# As an example if there is a 'memberOf' attribute with value:
#   cn=LensesAdmins,ou=Groups,dn=example,dn=com
# The regular expression will return 'LensesAdmins'.
# Group names are case sensitive.
lenses.security.ldap.plugin.group.extract.regex="(?i)cn=(\\w+),ou=Groups.*"

# This is the LDAP attribute that holds the user's full name. It's optional.
lenses.security.ldap.plugin.person.name.key = "sn"

As an example, the memberOf search may return two attributes for user Mark:

attribute  value
---------  ------------------------------------------
memberOf   cn=LensesAdmin,ou=Groups,dc=example,dc=com
memberOf   cn=RandomGroup,ou=Groups,dc=example,dc=com

The regular expression (?i)cn=(\\w+),ou=Groups.* will return these two regex group matches:

LensesAdmin
RandomGroup

If any of these groups exist in Lenses, Mark will be granted the permissions of the matching groups.

To learn more about permissions in Lenses, see the _user_management section.

Custom LDAP Plugin

If your LDAP doesn’t offer the memberOf functionality, or it isn’t enough alone —for example in Active Directory there are groups of groups— you can provide your implementation.

The project template for a custom implementation can be found on GitHub (Lenses LDAP Plugin Template) . Once you build your implementation, drop the jar file into the plugins directory and set the lenses.security.ldap.plugin setting to point to your implementation’s full classpath.

Don’t forget to grant to the Lenses LDAP account any permissions it may need for your plugin to work.

Options Table

LDAP Configuration Options Table
Key Description Optional Type Default
lenses.security.ldap.url
The LDAP server URL. TLS, StartTLS and
unencrypted connections are supported.
Example: ldaps://example.com:636
no string “n/a”
lenses.security.ldap.user
The LDAP account for Lenses. Must be able to
list users and their groups. The distinguished
name (DN) must be used. Example:
cn=lenses,ou=Services,dc=example,dc=com
no string n/a
lenses.security.ldap.password The LDAP account password. so string n/a
lenses.security.ldap.base
The LDAP base path for querying user accounts.
All user accounts that will be able to access
Lenses should be under this path.
Example: ou=Users,dc=example,dc=com
no string n/a
lenses.security.ldap.filter
The LDAP query filter for matching users. Lenses
will request all entries under the base path
that satisfy this filter. The result should be
unique: the user that logs in to Lenses. The
keyword <user> is replaced at runtime with
the Username that requests access.
yes string
(&
 (objectClass=person)
 (sAMAccountName=<user>)
)
lenses.security.ldap.plugin.class
The full classpath for the class that implements
the LDAP query for the user’s groups and
maps them to Lenses groups. You can use
the implementation that comes with Lenses
if your LDAP setup is supported.
yes string n/a
lenses.security.ldap.plugin.memberof.key
This key is used by the included LDAP plugin class
LdapMemberOfUserGroupPlugin. It expects the
LDAP user attribute that provides memberOf
information. In most implementations the attribute
has the same name, so you don’t have to set
anything.
yes string memberOf
lenses.security.ldap.plugin.group.extract.regex
This key is used by the included LDAP plugin class
LdapMemberOfUserGroupPlugin. It expects a
regular expression that will be used to extract
a part of the user’s groups. If this part matches a
Lenses group, the user will be granted all the
permissions of this group.
Lenses checks against the list of memberOf
attribute values and uses the first regex group
that is returned.
yes string (?i)CN=(\\w+),ou=Groups.*
lenses.security.ldap.plugin.person.name.key
This key is used by the included LDAP plugin class
LdapMemberOfUserGroupPlugin. It expects the
LDAP user attribute that provides the full name
of the user.
yes string sn
lenses.security.ldap.use.service.user.search
If set to true it uses the
lenses.security.ldap.user account to read the
groups of the current logged user. The default
behaviour (false) uses the current logged
user to read group memberships.
yes boolean false

Note

The configuration entries lenses.security.ldap.plugin.memberof.key, lenses.security.ldap.plugin.person.name.key, lenses.security.ldap.plugin.group.extract.regex, and lenses.security.ldap.plugin.person.name.key are specific to the default plugin class that comes with Lenses. A custom implementation may require different entries under lenses.security.ldap.plugin

Kerberos (SPNEGO)

In Kerberos mode, your browser will use the Simple and Protected GSSAPI Negotiation Mechanism (SPNEGO) to login to Lenses.

Before setting up Lenses with SPNEGO, it is important to make sure your browser does support this mechanism, and you are adequately familiar with the protocol and you have access to your Kerberos and/or Active Directory administrators.

Let’s look at an example of a Kerberos security setup:

# Kerberos settings

lenses.security.kerberos.service.principal="HTTP/lenses.url[@REALM]"
lenses.security.kerberos.keytab=/path/to/lenses.keytab

The SPNEGO-specific configuration is straightforward, you have to point Lenses to a password-less Kerberos keytab and specify the principal to use.

Your system should also provide a system-wide Kerberos configuration. Usually, for Linux distributions, this resides in the file /etc/krb5.conf which is populated with information about your KDC, Kerberos realm and other authentication-related settings. If there isn’t a global krb5.conf that Lenses can use, please ask your Kerberos administrator for one, then point Lenses to it via the LENSES_OPT environment variable:

export LENSES_OPTS="-Djava.security.krb5.conf=/path/to/krb5.conf

Once setup, your users should be automatically logged in whenever they visit the Lenses web interface or make a call to the /api/auth REST endpoint. If you are on a Microsoft Windows system, then logging into your Windows domain is usually sufficient to issue your Kerberos credentials. On a Linux environment, if you use Kerberos with PAM, your Kerberos credentials should be already available to Kerberos-enabled browsers. Otherwise, you will typically need to authenticate to the KDC manually using kinit at the command line and start your browser from the same terminal.

Group Mapping

A shortcoming of Kerberos is that by design it is just an authentication mechanism. It doesn’t provide any information about the user it authenticates except the user’s principal. As such it falls to the Lenses administrator to map users to groups.

This is done by adding the same user id to Lenses and link it to at least one group. To learn more about the permission model of Lenses, see the User Management section.

SPNEGO Principal

The Kerberos principal is not random in the SPNEGO protocol. When your browser tries to connect to a SPNEGO service it needs a ticket for it which is granted by the Key Distribution Center (KDC). In SPNEGO, the browser will always request a key from the KDC in the format HTTP/service.url@REALM. So, if your service is at service.example.com and your realm is EXAMPLE.COM, your browser will always request a ticket for the principal HTTP/service.example.com@EXAMPLE.COM. The realm usually can be omitted as it is part of the system-wide Kerberos settings.

To repeat one more time, if you setup Lenses at lenses.example.com, you need to ask your Kerberos or Active Directory administrator to create the principal HTTP/lenses.example.com and provide you with a password-less keytab for it.

Options Table

Kerberos Configuration Options Table
Key Description Optional Type Default
lenses.security.kerberos.service.principal
The Kerberos principal Lenses should use.
It must be present in the keytab and in
form below (SPNEGO requirement):
HTTP/lenses.address@REALM.COM
no string n/a
lenses.security.kerberos.keytab
Path to a Kerberos keytab that contains
the service principal. It should not
be password protected.
no string (path) n/a
lenses.security.kerberos.debug
Enable Java’s JAAS debugging information.
yes boolean false

Custom HTTP

In this mode, a custom, user-provided, class takes over authentication and authorization to Lenses using the users’ HTTP request headers. The authentication layer is separated from Lenses into your authentication solution. As an example, it would be possible to use JSON Web Tokens (JWT) injected via an authentication-proxy in-front of Lenses or any other single sign-on tokens your organization may use. The user-implemented class should process the request HTTP headers to extract the tokens and any other information it needs, ideally verifies them, then provides Lenses with the username and groups of the user.

An example of a security configuration with Custom HTTP:

# Just one setting for CUSTOM_HTTP, the full classpath
# of the security plugin implementation

lenses.security.plugin=my.custom.plugin.class.path

The only available option for this mode is lenses.security.plugin, which should point to the full Java classpath of the class implementing the required interface (HttpAuthenticationPlugin). Once you build your code, you can drop the required jar(s) inside the plugins directory or a subdirectory under it.

The interface of the Custom HTTP class:

public interface HttpAuthenticationPlugin {
    UserAndGroups authenticate(HttpRequest request);
}

The return object UserAndGroups should contain the username accepted to log in and the groups the person belongs to or raise an exception if the user is not allowed. To learn more about the permissions model of Lenses, check _user_management. To implement the interface, you need to create a project where this maven dependency needs to be added (here is the example for a Maven project):

<dependency>
    <groupId>com.landoop</groupId>
    <artifactId>lenses-security-http-plugin</artifactId>
    <version>1.0.0</version>
</dependency>

Example Code

A sample implementation can be found at GitHub. This code expects the header API_KEY based on which it performs a lookup to a mocked user-store. Let’s explore this example a bit further.

If you check the HeaderTokenAuthPlugin.java file inside the repository you will notice that the package has a classpath of io.lenses.security.auth.http.custom, therefore the full java classpath would be io.lenses.security.auth.http.custom.HeaderTokenAuthPlugin.

/*
First line of HeaderTokenAuthPlugin.java
*/

package io.lenses.security.auth.http.custom;

The expected header key is API_KEY [1]:

/*
First entry under public class in HeaderTokenAuthPlugin.java
*/

public class HeaderTokenAuthPlugin implements HttpAuthenticationPlugin {

  private static final String API_HEADER_NAME = "API_KEY";

The expected key values are one of [KEY-ADMIN, KEY-WRITE, KEY-READ]. Each value links to a different pair of user & group as shown under UserAndGroups.java.

/*
Entries under public class in UserAndGroups.java
*/

public class UserStore {

    private final Map<String, UserAndGroups> users = new HashMap<>();

    {
        users.put("KEY-ADMIN", new UserAndGroups("AdminUser", Collections.singleton("adminGroup")));
        users.put("KEY-WRITE", new UserAndGroups("WriteUser", Collections.singleton("writeGroup")));
        users.put("KEY-READ", new UserAndGroups("ReadUser", Collections.singleton("readGroup")));
        users.put("KEY-NODATA", new UserAndGroups("NoData", Collections.singleton("nodataGroup")));
    }

The security.conf syntax for the example above could be:

lenses.security.plugin=io.lenses.security.auth.http.custom.HeaderTokenAuthPlugin

The jar produced should be dropped inside the plugins directory. If you are using Lenses Box for development and testing, you may drop it under /plugins or /opt/lenses/plugins.

To test that everything works as expected, execute the following curl command.

curl --header "API_KEY: KEY-ADMIN" --compressed http://lenses.url/api/auth
[1]HTTP headers are case-insensitive. RFC 2616, section 4.2.

Single Sign On (SSO) - SAML 2.0

Lenses supports Single Sign On (SSO) authentication using the SAML 2.0 protocol. SSO allows you to authenticate and login your users using your organisation’s Identity Provider (IdP).

Lenses currently supports these Identity Providers:

To enable Lenses SSO, there are 2 steps:

  1. Configure your IdP to allow SSO for Lenses.
  2. Configure Lenses for SSO for your specific IdP.

Group Mapping

Each user that authenticates to Lenses, needs to belong to one or more Lenses groups. The SAML/SSO mechanism expects the Identity Provider to provide a list of groups for the user, which are then mapped map to Lenses groups. As such the implementation is provider specific.

In general:

  • All the user’s groups are provided by the IdP
  • They are then matched by name (case sensitive) or ID with the groups stored in Lenses (see details of each provider)
  • All the matching groups’ permissions are combined

Azure Groups

During authentication, Azure provides a list of the user’s group IDs. These IDs are in UUID (Universally Unique IDentifier) form. For Lenses to map them to a Lenses group, you need to create Lenses groups with the UUID as the name.

As an example, if you have an Engineers group with UUID ae3f363d-f0f1-43e6-8122-afed65147ef8, then you have to create a group with name ae3f363d-f0f1-43e6-8122-afed65147ef8 in Lenses.

../../_images/saml-lenses-group.png

Okta Groups

Thanks to the Okta configuration (see Okta), Lenses matches Okta groups by name (case-sensitive).

As an example, if you have an Engineers group in Okta, with the Lenses App assigned to it, then you have to simply create a group with name Engineers in Lenses.

../../_images/saml-okta-okta-group.png
../../_images/saml-lenses-groups.png

OneLogin Roles

Thanks to the OneLogin configuration (see OneLogin), Lenses matches OneLogin roles by name to Lenses groups (case-sensitive).

As an example, if you have an Engineers role in OneLogin, with the Lenses App assigned to it, then you have to simply create a group with name Engineers in Lenses.

../../_images/saml-onelogin-onelogin-role.png
../../_images/saml-lenses-groups.png

Keycloak Roles

Thanks to the Keycloak configuration (see Keycloak), Lenses matches Keycloak groups by name to Lenses groups (case-sensitive).

As an example, if you have an Engineers group in Keycloak, with the Lenses App assigned to it, then you have to simply create a group with name Engineers in Lenses.

../../_images/saml-keycloak-group.png
../../_images/saml-lenses-groups.png

Configure Lenses

Lenses SSO is configured in the security.conf configuration file.

Here’s a sample with the required configuration:

########################
# SSO SAML Configuration
########################

##################################
# Service Provider (SP) settings
##################################

# The HTTPS URL of the Lenses deployment.
# This needs to match the Service Provider (SP) URL
# given to the Identity Provider (IdP)
# as it will be used as part of the SAML handshake protocol.
lenses.security.saml.base.url = "https://my.lenses.com"


##################################
# Identity Provider (IdP) settings
##################################

# Provider type.
# Supported values:
# "azure"    - Microsoft Azure
# "okta"     - Okta
# "onelogin" - OneLogin
# "keycloak" - Keycloak
lenses.security.saml.idp.provider = "azure"

# XML File provided by the external Identity Provider.
# This is needed in order for Lenses SAML to understand how to communicate
# with the Idenity Provider.
lenses.security.saml.idp.metadata.file = "/path/to/saml-idp.xml"


##############################################
# Keystore configuration for SAML crypto needs
##############################################

# Location for the Java keystore file to be used for SAML crypto.
lenses.security.saml.keystore.location = "/path/to/keystore.jks"

# Password to for accessing the keystore.
lenses.security.saml.keystore.password = "my_keystore_password"

# Password to use for the SAML generated key within the keystore.
lenses.security.saml.key.password = "my_saml_key_password"

To configure Lenses against your IdP, use the XML file that you downloaded from your IdP: see Configure your IdP and set its location in lenses.security.saml.idp.metadata.file

Note

For SAML to work, Lenses should be served via TLS (SSL). The TLS may be provided by Lenses itself, or a TLS termination proxy in front.

Options Table

SAML Configuration Options Table
Key Description Optional Type Default
lenses.security.saml.base.url
The HTTPS URL of the Lenses deployment.
This needs to match the Service Provider (SP) URL
given to the Identity Provider (IdP)
as it will be used as part of the SAML handshake protocol.
e.g. https://my.lenses.com
no string n/a
lenses.security.saml.sp.entityid
The SAML Service Provider (SP) Entity ID for the Lenses instance.
This ID is communicated to the IdP and it will be used
as part of the SAML handshake protocol.
yes string
Same as
lenses.security.saml.base.url
lenses.security.saml.idp.provider
The type of the Identity Provider (IdP).
Supported values:
azure - Microsoft Azure
okta - Okta
onelogin - OneLogin
keycloak - Keycloak
no string n/a
lenses.security.saml.idp.metadata.file
XML File provided by the external Identity Provider.
This is needed in order for Lenses SAML to understand
how to communicate with the Idenity Provider.
e.g. /path/to/saml-idp.xml
no string n/a
lenses.security.saml.idp.session.lifetime.max
The maximum-duration-since-login allowed by Lenses to accept
from an IdP. If an IdP returns an authenticated user whose login
happened before this setting, Lenses will reject it.
It is a SAML safety measure that is usually not used.
The supported duration syntax can be found here.
yes string 100days
lenses.security.saml.keystore.location
Location for the Java keystore file to be used for SAML crypto.
e.g. /path/to/keystore.jks
no string n/a
lenses.security.saml.keystore.password
Password to for accessing the keystore.
e.g. my_keystore_password
no string n/a
lenses.security.saml.key.password
Password to use for the SAML generated key within the keystore.
e.g. my_saml_key_password
no string n/a

Configure your IdP

Instructions for the supported types of Identity Providers:

Microsoft Azure SSO

You can find more details in Azure’s SAML documentation.

  1. Prerequisites
  • Lenses will need to be registered with your Azure account as a “non-gallery application”
  • You will need an Azure Premium licence for that.
  1. Register Lenses as a non-gallery application.

    • Azure documentation here
    1. Go to Enterprise applications > + New Application
    2. Select Non-gallery application and choose a name for your Lenses installation e.g. lenses.io and click Add
    ../../_images/saml-azure-add-application.png
  2. Enable Single Sign On

    Select Set up single sign on > SAML

    ../../_images/saml-azure-enable-single-sign-on.png
  3. Basic SAML Configuration

    Edit the basic configuration section to set the Lenses-specific settings.

    ../../_images/saml-azure-basic-configuration.png

    1. Identifier (Entity ID): It should be the base.url of your lenses installation e.g. https://my.lenses.com

    2. Reply URL (Assertion Consumer Service URL): This is the Lenses API point for Azure to call back. Set it to [BASE_URL]/api/v2/auth/saml/callback?client_name=SAML2Client e.g. https://my.lenses.com/api/v2/auth/saml/callback?client_name=SAML2Client

    1. Sign on URL: same as (1) above.
  4. Expose Group information to SAML

    Edit User Attributes & Claims.

    1. Select Add a group claim.
    2. Select Security Groups
    3. Select Group ID from the Source attribute dropdown.
    ../../_images/saml-azure-expose-groups.png

    Note

    • Azure currently does not support exposing the Group name.
    • Instead it only exposes the Group ID which is a UUID e.g. 39f60346-7aea-4697-855b-1ef8fd5ef6b8
    • Due to this limitation, please use the UUIDs for naming the Lenses groups so that the group mapping works. and use the description field to put the group name.
  5. Download SAML Signing Certificate

    This section is where you will download the XML file with the Azure IdP metadata. That file will be then included in your Lenses configuration - see Configure Lenses

    ../../_images/saml-azure-signing-certificate.png

    Download the file from Federation Metadata XML. The file will be used in the Lenses security.conf configuration, see Configure Lenses

Okta

Lenses is available in Okta’s Application catalog.

  1. Prerequisites
  • Company Applications can be created in Okta’s Admin console.
  1. Add Lenses Application from Catalog

    Use Okta’s existing Lenses integration.

    ../../_images/saml-okta-lenses-app.png
    1. Go to Applications > Applications
    2. Click Add Application
    3. Search for Lenses
    4. Select the Lenses App by pressing Add.
  2. Fill in General Settings

    1. Application Label: Lenses
    2. Base URL: It should be the base.url of your lenses installation e.g. https://my.lenses.com
    3. Click Done
    ../../_images/saml-okta-general-settings.png
  3. Download IdP XML metadata

    This section is where you will download the XML file with the Okta IdP metadata. That file will be then included in your Lenses configuration - see Configure Lenses

    1. On the Sign On > Settings > SIGN ON METHODS section
    2. Click on Identity Provider metadata and download the XML data to a file.
    3. The file will be used in the Lenses security.conf configuration, see Configure Lenses
    ../../_images/saml-okta-idp-metadata.png

OneLogin

Lenses is available in OneLogin’s Application catalog.

  1. Prerequisites
  • Company applications can be added in OneLogin’s Administration console. Select Applications > Applications > Add App
  1. Add Lenses Application from Catalog

    Use OneLogin’s existing Lenses integration.

    ../../_images/saml-onelogin-lenses-connector.png
    1. Search for Lenses
    2. Select the Lenses App.
    3. (Optional) Add a description to your app.
    4. Click Save
    ../../_images/saml-onelogin-logos-setup.png
  2. Configure Lenses Endpoint

    Head to the Configuration section.

    1. Base URL: It should be the path from the base.url of your lenses installation e.g. my.lenses.com (without https://)
    2. Click Save
    ../../_images/saml-onelogin-saml-config.png
  3. Download IdP XML metadata

    This section is where you will download the XML file with the OneLogin IdP metadata. That file will be then included in your Lenses configuration - see Configure Lenses

    1. On the More Action button
    2. Click on SAML metadata and download the XML data to a file.
    3. The file will be used in the Lenses security.conf configuration, see Configure Lenses
    ../../_images/saml-onelogin-idp-metadata.png

Keycloak

You can find the main guide for setting SAML SSO in Keycloak’s SAML documentation.

  1. Prerequisites
  • SAML applications can be created in Keycloak’s Administration console.
  1. Create a new SAML application client

    ../../_images/saml-keycloak-create-client.png
    1. Go to Clients
    2. Click Create
    3. Client ID: It should be the base.url of your lenses installation e.g. https://my.lenses.com
    4. Client Protocol: Set it to saml
    5. Client SAML Endpoint: This is the Lenses API point for Okta to call back. Set it to [BASE_URL]/api/v2/auth/saml/callback?client_name=SAML2Client e.g. https://my.lenses.com/api/v2/auth/saml/callback?client_name=SAML2Client
    6. Click Save
    ../../_images/saml-keycloak-basic-client-config.png
  2. Set SAML settings

    Besides the defaults already set, change these:

    1. Name: Lenses
    2. (Optional) Add a description to your app.
    3. SAML Signature Name: KEY_ID
    4. Client Signature Required: OFF
    5. Force POST Binding: ON
    6. Front Channel Logout: OFF
    7. Force Name ID Format: ON
    8. Name ID Format: email
    9. Root URL: It should be the base.url of your lenses installation e.g. https://my.lenses.com
    10. Valid Redirect URIs: It should be the base.url of your lenses installation with a wildcard * e.g. https://my.lenses.com/*
    11. Click Save
    ../../_images/saml-keycloak-config-1.png
    ../../_images/saml-keycloak-config-2.png
  3. Map user Groups

    Configure Keycloak to communicate groups to Lenses. Head to the Mappers section.

    ../../_images/saml-keycloak-mappers.png
    1. Click Create
    2. Name: Groups
    3. Mapper Type: Group list
    4. Group attribute name: groups (case-sensitive)
    5. Single Group Attribute: ON
    6. Full group path OFF
    7. Click Save
    ../../_images/saml-keycloak-group-mapper.png
  4. Download IdP XML metadata

    This section is where you will download the XML file with the Keycloak IdP metadata. That file will be then included in your Lenses configuration - see Configure Lenses

    • Head to the URL [KEYCLOAK_BASE_URL]/auth/realms/demo/protocol/saml/descriptor e.g. https://my.keycloak.com/auth/realms/demo/protocol/saml/descriptor
    • This page should generate the XML metadata that you can download.

Account Locking

For BASIC and LDAP authentication type, there is the option to set a policy to temporarily lock the account when successive login attempts fail. Once the lock time window has passed the user can login again.

Enabling the functionality is driven by these two configuration entries. Both of them have to be available to enable the behaviour.

# The maximum number of failed login attempts before the account is locked. It has to be a positive number greater
# than 1
lenses.security.lockout.user.attempts.max = "5"

# The time in seconds to keep the account locked.
lenses.security.lockout.user.period.sec = "600"  #10 minutes