FeatureHub comes with a built-in identity system, which stores passwords in a securely salted fashion. It is fine to use if you don’t wish to federate your identity, and works well in small organisations. You do not need to configure anything to use the built-in identity system, it is there by default.
However, you may wish to federate your identity. FeatureHub lets you support both the internal system, or an external identity system (or several) as well as providing you the ability to turn off your internal system completely. You can migrate from one to the other as it will simply match email addresses. e.g. If you configure a user in the system using the identity firstname.lastname@example.org and then federate bar.com to an OAuth provider, the user will remain the same in the system, you do not need to recreate or delete the user.
Further, you can configure the system to disallow attempts at logging in to your FeatureHub instances if their user hasn’t already been created. This allows you to expose FeatureHub to your organisation’s IDP, but not let everyone from that IDP in.
FeatureHub supports the two main methods of identification - the more modern OAuth2 OpenID Connect, and the more Enterprise focused SAML2 standard. We added support for SAML as it supports many internal organisations methods of grouping users and determining who has access to a resources from that organisational level. Most OpenID providers do not provide this capability.
|it is important to note that if you are using an OAuth2 provider with FeatureHub, that it does not use the Access Token it receives from the OAuth provider to call back (except in the case of GitHub where it is required to understand the user’s name), it simply follows the standard OAuth2 Authorization Code Flow and requests an openid style id token. This contains the email address and username and FeatureHub will then drop the token from the supplier. No further callbacks are made.|
auth.disable-login- by default, disable-login for local is turned off (false). If you only want people to sign in via your IDP, turn this true
auth.userMustBeCreatedFirst- the user must exist in the database before they are allowed to login using an external auth provider. The default is false.
All of the following options allow you to specify a "code" which identifies the identity configuration. For both OAuth2
and SAML you can simply use the URL the FeatureHub home page would use itself. If your site is
https://featurehub.example.com, and you
were (for example), using a Microsoft SAML provider you had named
william then you would use:
https://featurehub.example.com/authentication/external-provider/william. Simply creating a button or link on your own internal documentation system
to link to that URL will start the process. It will redirect to your Identity Provider and then straight back into FeatureHub.
If you specify a single identity provider and no allowed login using the internal password system, this will automatically happen.
FeatureHub currently supports OAuth2 as a protocol, and currently three providers (Google, GitHub, Azure). It is built in such a way that you can easily support others.
oauth2.providers=[comma seperated list of providers] oauth2.redirectUrl=http://localhost:8085/oauth/auth oauth2.adminUiUrlSuccess=http://localhost:8085/ oauth2.adminUiUrlFailure=http://localhost:8085/oauth2-failure
oauth2.redirectUrl- In this case, this needs to be registered with your OAuth provider as a web callback url. The actual url will depend on where you have installed it, and it only has to be visible to browsers in your organisation.
adminUiUrlFailure- are links back to your running FeatureHub system and indicate where to go. FeatureHub will set a cookie with the necessary information to authenticate the user on success.
Basic details on setting up your credentials is
located in Google’s help documentation. It needs to be allowed access to the
profile (name) and
For FeatureHub, your properties file needs to add a few configuration items:
oauth2.providers=oauth2-google oauth2.providers.google.id=[CLIENT-ID] oauth2.providers.google.secret=[CLIENT-SECRET]
FeatureHub knows all of the URLs necessary to ask Google for the negotiation phase.
To authorise via GitHub, your properties file needs to add a few configuration items:
oauth2.providers=oauth2-github oauth2.providers.github.id=[CLIENT-ID] oauth2.providers.github.secret=[CLIENT-SECRET]
To obtain client id and secret follow these instructions to register OAuth app on Github under your organisation’s GitHub account.
Basic details of setting up Azure config are included here as they are a little difficult to find online. At the
moment we are requesting
profile scopes as only this combination provides us with the email
address and name of the person. FeatureHub does not attempt to modify any data on any Azure account.
The fields we need for Azure are:
oauth2.providers=oauth2-azure oauth2.providers.azure.tenant=[tenant-id] # the azure ones expire after 24 months (from may 2021) oauth2.providers.azure.id=[client-id] oauth2.providers.azure.secret=[client-secret - what Azure calls a "value"]
Open your Azure account, login and go here.
Add a New Registration
Choose the name - FeatureHub for instance and choose Single Tenant (the first option)
Click Register and in the details you will find "Application (client) id" - this is your
[client-id]for your configuration.
Next in the details find "Display (tenant) ID" - this is your
On the right side, find "Client credentials" and click the blue link that says "Add a certificate or secret".
At the bottom of the page, choose "+ New client secret". Give it a name and choose a period of time to issue it for and Add it.
At the bottom will now be listed your new secret, choose the Values column. Click the "copy" button to the right of it and paste that into the config under "[client-secret]". This is the last tiem you will see it as soon as you navigate away from that page, Azure will hide it from you.
You are now done setting up Azure.
Keycloak is new in 1.5.0. You need to select the realm the new client will be in, and then set up your new client. As part of that you will need to ensure:
it uses the openid-connect setup for your Client Protocol
the valid redirect URIs include the link to your Management Repository (e.g.
http://localhost:8085/oauth/authwhen using our example setups).
oauth2.providers=oauth2-keycloak oauth2.providers.keycloak.secret=[insert-client-secret] oauth2.providers.keycloak.url=[the main url for your keycloak server, e.g. http://localhost:8080] oauth2.providers.keycloak.realm=[your realm name] oauth2.providers.keycloak.id=[the name of the client you created]
This will enable Keycloak to be used as your authentication provider, so users can login using that method.
If you have an IdP that isn’t listed above, you can still likely use it, its just a bit more configuration. This option requires you to provide your own icon, background colour and login text. Remember, any and all of these can be environment variables.
oauth2.providers=oauth2-generic oauth2.providers.generic.auth-url=[full auth url, including https] oauth2.providers.generic.token-url=[full token url, including https] oauth2.providers.generic.id=[required, client-id] oauth2.providers.generic.secret=[required, client-id] oauth2.providers.generic.scope=[defaults to "profile email"] oauth2.providers.generic.name-fields=[optional, field to find inside JWT for the user's name, defaults to "name"] oauth2.providers.generic.email-field[optional, field to find inside JWT for user's email, defaults to "email"] oauth2.providers.generic.icon.url=[required, full icon url, including https] oauth2.providers.generic.icon.background-color=[required, background colour in 0x format, e.g. 0xFFF44336 is a redish colour] oauth2.providers.generic.icon.text=[required,text to appear on button] oauth2.providers.generic.token-form-pairs=[optional, map-format, gets added to form body of token request] oauth2.providers.generic.token-header-pairs=[optional, map-format, gets added to the token request]
map-format are key-value pairs separated by
= - e.g.
If your IdP needs the client secret to be Base64 encoded in the header, add this configuration:
To use SAML you need to configure a number of other items, and you need to have generated - or know your X.509 Certificate and Private Key. If you do not have either of these, you can generate these on a Mac or Unix machine with:
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt
You will not have to provide either of these to the SAML IdP as the IdP can make a request to your Metadata Endpoint URL to retrieve them. If it cannot do so, you can make a request in your own browser to the URL, copy the result and upload it to your IdP manually.
FeatureHub allows you to configure as many SAML providers as you like, they need to be listed as a comma-separated list in the config, e.g:
saml.idp-providers=sample- Whatever name you give it becomes part of the URL - so you will get urls
/saml/sample/authand '/saml/sample/metadata` - see below for more details on these URLs.
sample is used here because it is the name you have given to the provider, but you should make it meaningful, e.g. google, microsoft, auth0, okta - etc.
The Metadata gives FeatureHub all the information it requires to know how to talk to the iDP. It is a file or a url that FeatureHub when starting up can use to get the metadata. There are three ways to load this data, one is required:
saml.sample.idp.metadata-file- gives an absolute filename for SAML metadata, OR
saml.sample.idp.metadata-text- gives the full text of the metadata file (e.g. load into environment variable), OR
saml.sample.idp.entity-id- this gives the URL location of the metadata that you can download. This is the least reliable option as the URL might not be available at times, but it is also the most up to date. Some providers (e.g. Google) don’t provide this.
FeatureHub will use the standard iDP Metadata method to figure out what the Single Sign On URL is for that SAML vendor.
There are three endpoints that FeatureHub provides that are of use to you:
/sso- this is the endpoint used when the SAML iDP is calling back to you, it is called the Assertion Consumer Service URL, or ACS URL for short.
/metadata- this is the endpoint which provides the details about the FeatureHub service to the remote site, it is also called the SP Entity ID. It provides the remote side information about the X.509 Certificate that is being used and confirms the Issuer of the request (your site)
/auth- this redirects to your iDP - it is a GET request and it allows you to create your own landing page, or a link on your corporate website that will end up redirecting to FeatureHub. It is not used by FeatureHub itself.
Related to these is a further mandatory config:
saml.google.sp.base-url- To be able to figure out what the URL is for FeatureHub’s own metadata, you need to tell the SAML config where you have mounted FeatureHub’s SAML links. E.g. if you have mounted at a root location like
https://featurehub.somesite.comor at an offset within your organisation’s website because you have a partitioned site, like
The two certificates need to be provided to FeatureHub without their surrounding comments (
BEGIN PRIVATE KEY, etc).
saml.google.sp.x509-cert- (required) the full text of the X509 Certificate
saml.google.sp.x509-cert-new- (optional) an optional extra X509 Certificate if yours is expiring
saml.google.sp.private-key- (required) the full private key (minus comments)
If you are using a properties file, you can do line continuations with a
\ character, see below for an
When you set up your SAML provider, please provide the following:
Further we use standard OASIS codes for containing the Display Name and/or the First Name and Last name. Either the display name or the First Name/Last Name must be provided, there are no other requirements.
Your SAML provider will ask you what extra attributes are required:
Last Name =
First Name =
Display Name =
For extra security, it is recommended that you list the email domains that are allowed to use SAML, the email address coming through will have its domain name extracted and compared against the list you provide. There is no regex or other pattern matching, exact domain names (all forced to lower case) need to be provided.
saml.google.email-domains- a comma separated list of valid domains. If empty or not provided then all email addresses are accepted but the global rule of whether the account must be created first remains in place.
You must specify the appearance of the button as it appears for login for FeatureHub. If you don’t specify these, then there will be no login button on the FeatureHub page, but you can still login using your SAML provider (as covered under Logging in via your own login page)
saml.google.login.icon-url- (required) the full url of the icon, which must be 48x48 pixels, preferably as a PNG
saml.google.login.button-background-color- (required) a colour understood by a browser, usually specified in hex, e.g.
saml.google.login.button-text- (required) the text to show on the button
This is an example of a Google style config.
saml.idp-providers=google saml.google.idp.metadata-file=/etc/config/GoogleIDPMetadata.xml saml.google.login.icon-url=https://some-icon saml.google.login.button-background-color=0xCAE8DC saml.google.login.button-text=Your company saml.google.sp.base-url=https://c6a0-203-118-154-3.ngrok.io saml.google.sp.x509-cert=MIIDjDCCAnQCCQDsBzl7KNcwlzANBgkqhkiG9w0BAQsFADCBhzELMAkGA1UEBhMC\ TloxDjAMBgNVBAgMBVlva3VtMRQwEgYDVQQHDAtZb2t1bSBEb2t1bTEWMBQGA1UE\ CgwNRG9rdW0gSW5jIEx0ZDEWMBQGA1UEAwwNeW9rb20uZXhhbXBsZTEiMCAGCSqG\ SIb3DQEJARYTbWluZUBtYWlsaW5hdG9yLmNvbTAeFw0yMjA1MjgwNzIwNTVaFw0y\ MzA1MjgwNzIwNTVaMIGHMQswCQYDVQQGEwJOWjEOMAwGA1UECAwFWW9rdW0xFDAS\ BgNVBAcMC1lva3VtIERva3VtMRYwFAYDVQQKDA1Eb2t1bSBJbmMgTHRkMRYwFAYD\ blahblah saml.google.sp.private-key=MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHtuPKNqou4hFz\ jz2gop21BALcf+/+WrZrXKSaqahBv+tf5KMkQUtft4agcgF5eEedoSVC+Lm7VCFg\ fem+v5NvqX+E9v1G7ptqb1ECuc9mwphTeuzERAZ1u2P0N5ZY5JMGfBTXt7jPyLxJ\ YZALwd/WCBETMRA1PQkltwbGC9N8ai5Ug6gH+nydeak7QRKmuXGUpyd54GzdjA9V\ K2MZ6aCi1oRVLjyRuxCt1KXFG84bi3RWIlNhtYlDGWMq3YDmV2NPhhBdkWOY+lom\ 1N9J7qo7dkeiXG38VhS5hsilY0/95aCiBfQRGJLCtQkl/aM26W5/gi2HF+3hZ4mK\ SiTQWlIrAgMBAAECggEAOyC3oie7DPRbbFYtTcC3Zl9QpY2vNSQQPAsKpMu0B/tV\ KWfcsSAvu5/vWNNIAnmM4mtSR9ixzHdlBldg+9tmQDnzih9B7103YDSizGbMs8TL\ KnQLYzQsoXCgcC6A8cKCkPnthcxcCBCLRkJ/TivRJGHxBDiTbt+qNKNSexIHRB74\ more-private-key-goodness\ CHtOi3mAkRWCKQIw0MhxujNe