Git Product home page Git Product logo

tyk-identity-broker's Introduction

Table of Contents

Tyk Identity Broker (TIB)

What is the Tyk Identity Broker?

The Tyk Identity Broker provides a service-level component that enables delegated identities to be authorized and provide authenticated access to various Tyk-powered components such as the Tyk Dashboard, the Tyk Developer Portal and Tyk Gateway API flows such as OAuth access tokens, and regular API tokens.

image

Requirements and dependencies

TIB requires:

  • Tyk Gateway v1.9.1+
  • Redis
  • Tyk Dashboard v0.9.7.1+ (Only if you want to do SSO to Tyk Dashbaord UI or Tyk Developer Portal)

Installation

You can install via Docker https://hub.docker.com/r/tykio/tyk-identity-broker/

Of via packages (deb or rpm): https://packagecloud.io/tyk/tyk-identity-broker/install#bash-deb

Run via Docker

To run the container, you can use the following command (assuming that you run it from the directory which contains tib.conf and profiles.json files, which must be edited according to How to configure TIB section before running it):

docker run -p 3010:3010 -v $(pwd)/tib.conf:/opt/tyk-identity-broker/tib.conf -v $(pwd)/profiles.json:/opt/tyk-identity-broker/profiles.json tykio/tyk-identity-broker

Usage

No command line arguments are needed, but if you are running TIB from another dir or during startup, you will need to set the absolute paths to the profile and config files

Usage of ./tyk-auth-proxy:
  -c=string
		Path to the config file (default "tib.conf")
  -p#=string
		Path to the profiles file (default "profiles.json")

Log level

You set the log level using the environment variable TYK_LOGLEVEL

Possible levels: "debug" , "error", "warn" and "info" which is also the default.

For instance for debug export TYK_LOGLEVEL=debug

How it works

Tyk Identity Broker provides a simple API, which traffic can be sent through, the API will match the request to a profile which then exposes two things:

  • An Identity Provider - the thing that will authorize a user and validate their identity
  • An Identity Handler - the thing that will authenticate a user with a delegated service (in this case, Tyk)

Identity Providers

Identity providers can be anything, so long as they implement the tap.TAProvider interface. Bundled with TIB at the moment you have three providers:

  1. Social - Provides OAuth handlers for many popular social logins (such as Google, Github and Bitbucket), as well as general OpenID Connect support
  2. LDAP - A simple LDAP protocol binder that can validate a username and password against an LDAP server (tested against OpenLDAP)
  3. Proxy - A generic proxy handler that will forward a request to a third party and provides multiple "validators" to identify whether a response is successful or not (e.g. status code, content match and regex)
  4. SAML - Provides a way to authenticate against a SAML IDP.

Identity Handlers

An identity handler will perform a predefined set of actions once a provider has validated an identity, these actions are defined as a set of action types:

Pass through or redirect user-based actions

  • GenerateOrLoginDeveloperProfile - Will create or login a user to the Tyk Developer Portal
  • GenerateOrLoginUserProfile - Will log a user into the dashboard (this does not create a user, only drops a temporary session for the user to have access)
  • GenerateOAuthTokenForClient - Will act as a client ID delegate and grant an Tyk-provided OAuth token for a user using a fragment in the redirect URL (standard flow)

** Direct or redirect **

  • GenerateTemporaryAuthToken - Will generate a Tyk standard access token for the user, can be delivered as a redirect fragment OR as a direct API response (JSON)

These are actions are all handled by the tap.providers.TykIdentityHandler module which wraps the Tyk Gateway, Dashboard and Admin APIs to grant access to a stack.

Handlers are not limited to Tyk, a handler can be added quite easily by implementing the TAProvider so long as it implements this pattern and is registered it can handle any of the above actions for it's own target.

How to configure TIB

Tyk Identity Broker is configured through two files: The configuration file (tib.conf) and the profiles file (profiles.json). TIB can also be managed via the REST API (detailed below) for automated configurations.

The tib.conf file

{
	"Secret": "test-secret",
	"HttpServerOptions": {
		"UseSSL": true,
		"CertFile": "./certs/server.pem",
		"KeyFile": "./certs/server.key"
	},
	"SSLInsecureSkipVerify": true,
	"BackEnd": {
		"Name": "in_memory",
		"IdentityBackendSettings": {
			"Hosts" : {
				"localhost": "6379"
			},
			"Password": "",
			"Database": 0,
			"EnableCluster": false,
			"MaxIdle": 1000,
			"MaxActive": 2000
		}
	},
	"TykAPISettings": {
		"GatewayConfig": {
			"Endpoint": "http://{GATEWAY-DOMAIN}",
			"Port": "80",
			"AdminSecret": "{GATEWAY-SECRET}"
		},
		"DashboardConfig": {
			"Endpoint": "http://{DASHBOARD-DOMAIN}",
			"Port": "3000",
			"AdminSecret": "{ADMIN-DASHBOARD-SECRET}"
		}
	}
}

The various configuration options are outlined below:

Secret

The Gateway API secret to configure the Tyk Identity Broker remotely.

HttpServerOptions.UseSSL

Set this to true to turn on SSL for the server, this is highly recommended.

HttpServerOptions.CertFile

The path to the certificate file for this server, required for SSL

HttpServerOptions.KeyFile

The path to the key file for this server, required for SSL

SSLInsecureSkipVerify

If you run a local IDP, like Ping, with an untrusted SSL certificate, you can now turn off the client SSL verification by setting SSLInsecureSkipVerify to true. This is useful when using OpenID Connect (OIDC). During the authorization there are calls to the https://{IDP-DOMAIN}/.well-know/openid-configuration and other endpoints to avoid error in case the certificate was signed by unknown authority

BackEnd

TIB is quite modular and different back-ends can be generated quite easily, out of the Box, TIB will store profile configurations in memory, which does not require any new configuration.

For Identity Handlers that provide token-based access, it is possible to enforce a "One token per provider, per user" policy, which keeps a cache of tokens assigned to identities in Redis, this is so that the broker can be scaled and share the cache across instances.

Since profiles are unlikely to change often, profiles are kept in-memory, but can be added, removed and modified using an API for automated setups if required.

BackEnd.Hosts

Add your Redis hosts here as a map of hostname:port. Since TIB uses the same cluster driver as Tyk, it is possible to have TIB interact with your existing Redis cluster if you enable it.

BackEnd.Password

The password for your Redis DB (recommended)

BackEnd.Database

If you are using multiple databases (not supported in Redis cluster), let TIB know which DB to use for Identity caching

BackEnd.EnableCluster

If you are using Redis cluster, enable it here to enable the slots mode

BackEnd.MaxIdle

Max idle connections to Redis

BackEnd.MaxActive

Max active Redis connections

TykAPISettings

This section enables you to configure the API credentials for the various Tyk Components TIB is interacting with.

TykAPISettings.GatewayConfig.Endpoint

The Hostname of the Tyk Gateway (this is for token generation purposes)

TykAPISettings.GatewayConfig.Port

The Port to use on the Tyk Gateway host

TykAPISettings.GatewayConfig.AdminSecret

The API secret for the Tyk Gateway API

TykAPISettings.DashboardConfig.Endpoint

The hostname of your Dashboard API

TykAPISettings.DashboardConfig.Port

The port of your Dashboard API

TykAPISettings.DashboardConfig.AdminSecret

The high-level secret for the Dashboard API. This is required because of the SSO-nature of some of the actions provided by TIB, it requires the capability to access a special SSO endpoint in the Dashboard Admin API to create one-time tokens for access.

The profiles.json file

The Profiles configuration file outlines which identity providers to match to which handlers and what actions to perform. The entries in this file encapsulate the activity for a single endpoint based on the ID and provider name.

The file is JSON object which is essentially a list of objects:

[{
	"ActionType": "GenerateOrLoginUserProfile",
	"ID": "1",
	"IdentityHandlerConfig": {},
	"OrgID": "53ac07777cbb8c2d53000002",
	"CustomUserIDField": "FIELD-NAME",
	"ProviderConfig": {
		"CallbackBaseURL": "http://tib.domain.com:3010",
		"FailureRedirect": "http://tib.domain.com:3000/?fail=true",
		"UseProviders": [{
			"Key": "GOOGLE-OAUTH-TOKEN",
			"Name": "gplus",
			"Secret": "GOOGLE OAUTH SECRET",
			"SkipUserInfoRequest": false
		}]
	},
	"ProviderConstraints": {
		"Domain": "tyk.io",
		"Group": ""
	},
	"ProviderName": "SocialProvider",
	"ReturnURL": "http://tyk-dashboard.domain.com:3000/tap",
	"Type": "redirect"
}, {
	"ActionType": "GenerateOAuthTokenForClient",
	"ID": "2",
	"IdentityHandlerConfig": {
		"DashboardCredential": "ADVANCED-API-USER-API-TOKEN",
		"DisableOneTokenPerAPI": false,
		"OAuth": {
			"APIListenPath": "oauth-1",
			"BaseAPIID": "API-To-GRANT-ACCESS-TO",
			"ClientId": "TYK-OAUTH-CLIENT-ID",
			"RedirectURI": "http://your-app-domain.com/target-for-fragment",
			"ResponseType": "token",
			"Secret": "TYK-OAUTH-CLIENT-SECRET"
		}
	},
	"MatchedPolicyID": "POLICY-TO-ATTACH-TO-KEY",
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"FailureRedirect": "http://yourdomain.com/failure-url",
		"LDAPAttributes": [],
		"LDAPUseSsl": false,
		"LDAPBaseDN": "cn=dashboard,ou=Group,dc=ldap,dc=tyk-test,dc=com",
		"LDAPEmailAttribute": "mail",
		"LDAPSearchScope": 2,
		"LDAPFilter": "((objectCategory=person)(objectClass=user)(cn=*USERNAME*))",
		"LDAPPort": "389",
		"LDAPServer": "localhost",
		"LDAPUserDN": "cn=*USERNAME*,cn=dashboard,ou=Group,dc=ldap,dc=tyk-test,dc=com"
	},
	"ProviderName": "ADProvider",
	"ReturnURL": "",
	"Type": "passthrough"
}]

Each item in a policy list dictates how that component will behave with the underlying services it is trying to talk to. In the above two examples, we have a social provider, that will allow Dashboard access to Google plus users that are part of the "tyk.io" domain. In the second example, we are generating an OAuth token for users that are validated via an LDAP server.

DashboardCredential - The credential of the dashboard user (that are used to login the UI or in the Dashboard API endpoints, not for the Admin Dashboard APIs)

In the following sections we outline multiple configurations you can use for Identity Provision and Handling

Using Identity Providers

Tyk Identity Broker comes with a few providers built-in, these are specialized around a few use cases, but we focus primarily on:

  • Enabling easy access via social logins to the developer portal (e.g. GitHub login)
  • Enabling internal access to the dashboard (e.g. via LDAP/ActiveDirectory)
  • Enabling easy token generation from a third party for things such as mobile apps and webapps without complex configuration

This next section outlines how to configure the various built-in providers.

Social

The social provider is a thin wrapper around the excellent goth social auth library, modified slightly to work with a multi-tenant structure. The social provider should provide seamless integration with:

  • Bitbucket
  • Digital Ocean
  • Dropbox
  • Facebook
  • GitHub
  • Google+
  • Linkedin
  • Twitter
  • SalesForce
  • Any OpenID Connect provider

The social provider is ideal for SSO-style logins for the dashboard or for the portal, for certain providers (mainly Google+), where email addresses are returned as part for the user data, a constraint can be added to validate the users domain. This is useful for Google For Business Apss users that want to grant access to their domain users for the dashboard.

We've outlined a series of example configurations below for use with the social handler.

Authenticate a user for the portal using Google and a constraint:

The first thing to do with any social provider implementation is to make sure the OAuth client has been set up with the provider, and that the OAuth client has been set up with the correct callback URI.

Step 1 Set up an OAuth client with google apps

  1. Go to the Google Developer Console and create a new app
  2. Register a new OAuth client, lets call it WebApp 1 (Select "New Credentials -> OAuth Client ID")
  3. Select Web App
  4. Add the following URL (modified for your domain) to the "Authorized redirect URIs" section: http://tib-hostname:TIB-PORT/auth/{PROFILE-ID}/gplus/callback

Save the client and take note of the secret and ID.

What did we just do?

We created a new OAuth client in Google apps that has a registered call back URL for TIB, the callback is very important, as this is how Google will tell TIB about the user logging in, the callback URI is constructed as follows:

http://{TIB-HOST}:{TIB-PORT}/auth/{PROFILE-ID}/{PROVIDER-CODE}/callback

If you were to use twitter with a profile ID of 15, you would have a callback for twitter that looks like this:

http://{TIB-HOST}:{TIB-PORT}/auth/15/twitter/callback

Step 2 Create a profile object in profiles.json:

[{
	"ActionType": "GenerateOrLoginDeveloperProfile",
	"ID": "1",
	"IdentityHandlerConfig": {
		"DashboardCredential": "YOUR-DASHBOARD-USER-API-KEY"
	},
	"OrgID": "YOUR-ORG-ID",
	"ProviderConfig": {
		"CallbackBaseURL": "http://{TIB-HOST}:{TIB-PORT}",
		"FailureRedirect": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/login/",
		"UseProviders": [{
			"Name": "gplus",
			"Key": "GOOGLE-OAUTH-CLIENT-KEY",
			"Secret": "GOOGLE-OAUTH-CLIENT-SECRET"
		}]
	},
	"ProviderConstraints": {
		"Domain": "yourdomain.com",
		"Group": ""
	},
	"ProviderName": "SocialProvider",
	"ReturnURL": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/sso/",
	"Type": "redirect"
}]

This profile basically tells TIB to load a profile into memory with the ID of 1, that it should login or generate a developer profile via Google Plus, and it should only allow users from yourdomain.com domain-based email accounts.

The Return URL here is important, and is only provided in the latest version of Tyk Dashboard, as it makes use of new API endpoints to generate the SSO tokens required to allow remote access.

If your portal is configured under a different root (e.g. /, then replace the `/portal' component of the URLs with that of your actual portal.)

Step 3 - Make a request to your TIB endpoint in your browser

Now, start TIB by entering:

./tib

And then point your browser at:

http://{TIB-HOST}:{TIB-PORT}/auth/1/gplus

You will be asked to log into your account (make sure it is one that satisfies the constraints!), and once logged in, you should be redirected back via the TIB proxy to your portal, as a logged in user.

This user will be created with some user profile data, the user can edit and change their email address, but continue to log in with the same Google account (this data is stored separately).

Authenticate a user for the dashboard using Google and a constraint:

Similarly to the above, if we have our callback URL and client IDs set up with Google, we can use the following profile setup to access our developer portal using a social provider:

{
	"ActionType": "GenerateOrLoginUserProfile",
	"ID": "2",
	"IdentityHandlerConfig": null,
	"MatchedPolicyID": "1C",
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"CallbackBaseURL": "http://\:{TIB-PORT}",
		"FailureRedirect": "http://{DASH-DOMAIN}:{DASH-PORT}/?fail=true",
		"UseProviders": [{
			"Name": "gplus",
			"Key": "GOOGLE-OAUTH-CLIENT-KEY",
			"Secret": "GOOGLE-OAUTH-CLIENT-SECRET"
		}]
	},
	"ProviderConstraints": {
		"Domain": "yourdomain.com",
		"Group": ""
	},
	"ProviderName": "SocialProvider",
	"ReturnURL": "http://{DASH-DOMAIN}:{DASH-PORT}/tap",
	"Type": "redirect"
}

It is worth noting in the above configuration that the return URL's have changed for failure and return states.

The login to the portal, much like the login to the dashboard, makes use of a one-time nonce to log the user in to the session. The nonce is only accessible for a few seconds. It is recommended that in production use, all of these transactions happen over secure SSL connections to avoid MITM snooping.

OpenID Connect

Similar to Google or Twitter auth, you can configure TIB to work with any OpenID Connect provider, like Okta, Ping Federate, or anything else. Just in addition to Key and Secret you need to provide Discovery URL, which you should find in documentation of your OpenID provider. Below is example configuration of Okta integration:

	"ProviderConfig": {
		"CallbackBaseURL": "http://{TIB-HOST}:{TIB-PORT}",
		"FailureRedirect": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/login/",
		"UseProviders": [{
			"Name": "openid-connect",
			"Key": "OKTA-CLIENT-KEY",
			"Secret": "OKTA-CLIENT-SECRET",
			"Scopes": ["openid", "email"],
			"DiscoverURL": "https://<your-okta-domain>/.well-known/openid-configuration",
			"SkipUserInfoRequest": false
		}]
	},

By default, TIB uses the value of the subject field, returned by UserInfo Endpoint, to generate userId for Dashboard SSO. Please ensure that your Identity Provider is not returning URL in subject field. If that's the case you should specify another field which uniquely identifies the user. You can specify the field name by setting CustomUserIDField in profile.json file.

TIB can also be configured to use the openid email claim. This claim must be requested for Portal SSO to work, but it can also be used for Dashboard SSO. Some OpenID providers return this claim by default, but not all, in which case the openid email claim needs to be included, as per the example above.

If you are getting 403 error, it can be that your OpenID provider requires providing client_id and secret_id via token url instead of basic http auth, and you need to add "DisableAuthHeader": true option to your provider configuration in "UseProviders" section.

Some Identity providers do not have support for userinfo endpoint, so you can optionally disable it using SkipUserInfoRequest flag, and rely only on information inside the ID token.

Salesforce

Similar to other social accounts, you can add support of Salesforce by specifying Provider Name as salesforce.

{
	"ProviderConfig": {
		"CallbackBaseURL": "http://tib.domain.com:3010",
		"FailureRedirect": "http://tib.domain.com:3000/?fail=true",
		"UseProviders": [{
			"Name": "salesforce",
			"Key": "SF-CLIENT-KEY",
			"Secret": "SF-CLIENT-SECRET",
		}]
	},
}

SSO for Salesforce Community is handled differently. Instead of using salesforce provider type, you should use openid-connect and set user_id in CustomUserIDField field. Here is sample profile.json file for community

{
	"CustomUserIDField": "user_id",
	"ProviderConfig": {
		"CallbackBaseURL": "http://tib.domain.com:3010",
		"FailureRedirect": "http://tib.domain.com:3000/?fail=true",
		"UseProviders": [{
			"Name": "openid-connect",
			"Key": "SF-CLIENT-KEY",
			"Secret": "SF-CLIENT-SECRET",
			"DiscoverURL": "https://community_url/.well-known/openid-configuration"
		}]
	},
}

Create an OAuth token (with redirect) for users logging into your webapp or iOS app via Google:

A common use case for Tyk Gateway users is to enable users to log into a web app or mobile app using a social provider such as Google, but have that user use a token in the app that is time-delimited and issued by their own API (or in this case, Tyk).

Tyk can act as an OAuth provider, but requires some glue code to work, in particular, generating a token based on the authentication of a third party, which needs to run on a server hosted by the owner of the application. This is not ideal in many scenarios where authentication has been delegated to a third-party provider (such as Google or GitHub).

In this case, we can enable this flow with Tyk Gateway by Using TIB.

What the broker will do is essentially the final leg of the authentication process without any new code, simply sending the user via TIB to the provider will suffice for them to be granted an OAuth token once they have authenticated in a standard, expected OAuth pattern.

Assuming we hav created an client ID and secret in Google Apps to grant us access to the users data, we need those details, and some additional ones from Tyk itself:

Step 1 - Create an OAuth Client in Tyk Dashboard

TIB will use the OAuth credentials for GPlus to access and authenticate the user, it will then use another set of client credentials to make the request to Tyk to generate a token response and redirect the user, this means we need to create an OAuth client in Tyk Dashboard before we can proceed.

One quirk with the Tyk API is that requests for tokens go via the base APIs listen path ({listen_path}/oauth/authorize), so we will need to know the listen path and ID of this API so TIB can make the correct API calls on your behalf.

{
	"ActionType": "GenerateOAuthTokenForClient",
	"ID": "3",
	"IdentityHandlerConfig": {
		"DashboardCredential": "{DASHBOARD-API-ID}",
		"DisableOneTokenPerAPI": false,
		"OAuth": {
			"APIListenPath": "{API-LISTEN-PATH}",
			"BaseAPIID": "{BASE-API-ID}",
			"ClientId": "{TYK-OAUTH-CLIENT-ID}",
			"RedirectURI": "http://{APP-DOMAIN}:{PORT}/{AUTH-SUCCESS-PATH}",
			"ResponseType": "token",
			"Secret": "{TYK-OAUTH-CLIENT-SECRET}"
		}
	},
	"MatchedPolicyID": "567a86f630c55e3256000003",
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"CallbackBaseURL": "http://{TIB-DOMAIN}:{TIB-PORT}",
		"FailureRedirect": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/login/?fail=true",
		"UseProviders": [{
			"Key": "GOOGLE-OAUTH-CLIENT-KEY",
			"Name": "gplus",
			"Secret": "GOOGLE-OAUTH-CLIENT-SECRET"
		}]
	},
	"ProviderName": "SocialProvider",
	"ReturnURL": "",
	"Type": "redirect"
}

There's a few new things here we need to take into account:

  • API-LISTEN-PATH - This is the listen path of your API, TIB uses this to generate the OAuth token
  • BASE-API-ID - The base API ID for the listen path mentioned earlier, this forms the basic access grant for the token (this will be superseded by the MatchedPolicyID, but is required for token generation)
  • TYK-OAUTH-CLIENT-ID - The client ID for this profile within Tyk Gateway
  • TYK-OAUTH-CLIENT-SECRET - The Client secret for this profile in Tyk Gateway
  • RedirectURI: http://{APP-DOMAIN}:{PORT}/{AUTH-SUCCESS-PATH} - The Redirect URL set for this profile in the Tyk Gateway
  • ResponseType - This can be token or authorization_code, the first will generate a token directly, the second will generate an auth code for follow up access. For SPWA and Mobile Apps it is recommended to just use token

When TIB successfully authorizes the user, and generates the token using the relevant OAuth credentials, it will redirect the user to the relevant redirect with their token or auth code as a fragment in the URl for the app to decode and use as needed.

There is a simplified flow which does not require a corresponding OAuth client in Tyk Gateway, and can just generate a standard token with the same flow.

LDAP

The LDAP Identity Provider is experimental currently and provides limited functionality to bind a user to an LDAP server based on a username and password configuration. The LDAP provider currently does not extract user data from the server to populate a user object, but will provide enough defaults to work with all handlers.

Log into Tyk Dashboard using LDAP

{
	"ActionType": "GenerateOrLoginUserProfile",
	"ID": "4",
	"OrgID": "{YOUR-ORG-ID}",
	"ProviderConfig": {
		"LDAPUseSSL": false,
		"FailureRedirect": "http://{DASH-DOMAIN}:{DASH-PORT}/?fail=true",
		"LDAPAttributes": [],
		"LDAPPort": "389",
		"LDAPServer": "localhost",
		"LDAPUserDN": "cn=*USERNAME*,cn=dashboard,ou=Group,dc=test-ldap,dc=tyk,dc=io"
	},
	"ProviderName": "ADProvider",
	"ReturnURL": "http://{DASH-DOMAIN}:{DASH-PORT}/tap",
	"Type": "passthrough"
}

TIB can pull a username and password out of a request in two ways:

  1. Two form fields called "username" and "password"
  2. A basic auth header using the Basic Authentication standard form

By default, TIB will look for the two form fields. To enable Basic Auth header extraction, add "GetAuthFromBAHeader": true to the ProviderConfig section.

The request should be a POST. Example curl command can look like: curl -X POST localhost:3010/auth/4/callback -F username=bob -F password=secret

Set LDAPUseSSL to true if you want to use LDAPS (LDAP over SSL).

If you make this request with a valid user that can bind to the LDAP server, Tyk will redirect the user to the dashboard with a valid session. There's no more to it, this mechanism is pass-through and is transparent to the user, with TIB acting as a direct client to the LDAP provider.

Note The LDAPUserDN field MUST contain the special *USERNAME* marker in order to construct the users OU properly.

Log into Tyk Portal using LDAP

LDAP requires little configuration, we can use the same provider config above, with one that logs us into the portal instead - notice the change in the handler configuration and the return URL:

{
	"ActionType": "GenerateOrLoginDeveloperProfile",
	"ID": "5",
	"IdentityHandlerConfig": {
		"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a"
	},
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"FailureRedirect": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/login/",
		"LDAPAttributes": [],
		"LDAPUseSSL": false,
		"LDAPPort": "389",
		"LDAPServer": "localhost",
		"LDAPUserDN": "cn=*USERNAME*,cn=dashboard,ou=Group,dc=test-ldap,dc=tyk,dc=io"
	},
	"ProviderConstraints": {
		"Domain": "",
		"Group": ""
	},
	"ProviderName": "ADProvider",
	"ReturnURL": "http://{PORTAL-DOMAIN}:{PORTAL-PORT}/portal/sso/",
	"Type": "passthrough"
}

Generate an OAuth Token using an LDAP login form

The configuration below will take a request that is posted to TIB, authenticate it against LDAP, if the request is valid, it will redirect to the Tyk Gateway clients Redirect URI with the token as a URL fragment:

{
	"ActionType": "GenerateOAuthTokenForClient",
	"ID": "6",
	"IdentityHandlerConfig": {
		"DashboardCredential": "{DASHBAORD-API-ID}",
		"DisableOneTokenPerAPI": false,
		"OAuth": {
			"APIListenPath": "{API-LISTEN-PATH}",
			"BaseAPIID": "{BASE-API-ID}",
			"ClientId": "{TYK-OAUTH-CLIENT-ID}",
			"RedirectURI": "http://{APP-DOMAIN}:{PORT}/{AUTH-SUCCESS-PATH}",
			"ResponseType": "token",
			"Secret": "{TYK-OAUTH-CLIENT-SECRET}"
		}
	},
	"MatchedPolicyID": "POLICY-ID",
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"FailureRedirect": "http://{APP-DOMAIN}:{PORT}/failure",
		"LDAPAttributes": [],
		"LDAPUseSSL": false,
		"LDAPPort": "389",
		"LDAPServer": "localhost",
		"LDAPUserDN": "cn=*USERNAME*,cn=dashboard,ou=Group,dc=ldap,dc=tyk-ldap-test,dc=com"
	}
	"ProviderName": "ADProvider",
	"ReturnURL": "",
	"Type": "passthrough"
}

Using two phase LDAP authentication

In some cases only privileged users are allowed perform LDAP search. In this case you can specify your admin user using LDAPAdminUser and LDAPAdminPassword options. TIB will perform initial bind as admin user, then will perform a LDAP lookup based on specified DN template or LDAPFilter, and will do bind one more time, with user DN.

{
    "ActionType": "GenerateOrLoginUserProfile",
    "ID": "4",
    "OrgID": "59fc80d9158519599ca23cfc",
    "ProviderConfig": {
        "FailureRedirect": "https://tyk-dashboard:3000/?fail=true",
        "LDAPPort": "389",
        "LDAPAdminUser": "admin",
        "LDAPAdminPassword": "password",
        "LDAPServer": "localhost",
        "LDAPUserDN": "uid=*USERNAME*,dc=example,dc=org"
    },
    "ProviderName": "ADProvider",
    "ReturnURL": "https://tyk-dashboard:3000/tap",
    "Type": "passthrough"
}

Proxy Identity Provider

The proxy identity provider is a generic solution to more legacy problems, as well as a way to handle flows such as basic auth access with third party providers or OAuth password grants where the request can just be passed through to the providing endpoint to return a direct response.

The proxy provider will take a request, proxy it to an upstream host, capture the response, and analyze it for triggers of "success", if the triggers come out as true, then the provider will treat the request as authenticated and hand over to the Identity Handler to perform whatever action is required with the user data.

Success can be triggered using three methods:

  1. Response code - e.g. if this is an API request, a simple "200" response would suffice to act as a successful authentication
  2. Response body exact match - You can have a base64 encoded body that you would expect as a successful match, if the two bodies are the same, then the request will be deemed successful
  3. Regex - Most likely, the response might be dynamic (and return a response code, timestamp or other often changing parameter), in which case you may want to just match the response to a regex.

These can be used in conjunction as gates, e.g. a response must be 200 OK and match the regex in order to be marked as successful.

JSON Data and Usernames

The Proxy provider can do some clever things, such as extract JSON data from the response and decode it, as well as pull username data from the Basic Auth header (for example, if your identity provider supports dynamic basic auth).

Logging into the dashboard using a proxy provider

{
	"ActionType": "GenerateOrLoginUserProfile",
	"ID": "7",
	"OrgID": "{YOUR-ORG-ID}",
	"ProviderConfig": {
		"AccessTokenField": "access_token",
		"ExrtactUserNameFromBasicAuthHeader": false,
		"OKCode": 200,
		"OKRegex": "",
		"OKResponse": "",
		"ResponseIsJson": true,
		"TargetHost": "http://{TARGET-HOSTNAME}:{PORT}/",
		"UsernameField": "user_name"
	},
	"ProviderName": "ProxyProvider",
	"ReturnURL": "http://{DASH-DOMAIN}:{DASH-PORT}/tap",
	"Type": "redirect"
}

Generating a standard Auth Token using a Proxy Provider

{
	"ActionType": "GenerateTemporaryAuthToken",
	"ID": "8",
	"IdentityHandlerConfig": {
		"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
		"DisableOneTokenPerAPI": false,
		"TokenAuth": {
			"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
		}
	},
	"MatchedPolicyID": "5654566b30c55e3904000003",
	"OrgID": "53ac07777cbb8c2d53000002",
	"ProviderConfig": {
		"AccessTokenField": "access_token",
		"ExrtactUserNameFromBasicAuthHeader": false,
		"OKCode": 200,
		"OKRegex": "",
		"OKResponse": "",
		"ResponseIsJson": true,
		"TargetHost": "http://{TARGET-HOSTNAME}:{PORT}/",
		"UsernameField": "user_name"
	},
	"ProviderName": "ProxyProvider",
	"ReturnURL": "",
	"Type": "passthrough"
}

SAML

SAML authentication is a way for a service provider, such as the Tyk Dashboard or Portal, to assert the Identity of a User via a third party.

Tyk Identity Broker can act as the go-between for the Tyk Dashboard and Portal and a third party identity provider. Tyk Identity broker can also interpret and pass along information about the user who is logging in such as Name, Email and group or role metadata for enforcing role based access control in the Tyk Dashboard.

Gateway & Dashboard pre-requisites

The Gateway will encode the certificate being used for SAML at the time of upload. In order for the dashboard to be able to use this certificate you will need to match the secret within tyk.conf with the tyk_api_config.secret tyk_analytics.conf. Alternatively you can enable security.private_certificate_encoding_secret in both tyk.conf for the gateway and tyk_analytics.conf for the dashboard.

SAML Glossary

SAML metadata is an XML document which contains information necessary for interaction with SAML-enabled identity or service providers. The document contains e.g. URLs of endpoints, information about supported bindings, identifiers and public keys. Once you create your TIB profile you can find the SP metadata file under {Dashboard HOST}/auth/{TIB Profile Name}/saml/metadata

The provider config for SAML has the following values that can be configured in a Profile:

SAMLBaseURL: The host of TIB that will be used in the metadata document for the Service Provider. This will form part of the metadata URL used as the Entity ID by the IDP. The redirects configured in the IDP must match the expected Host and URI configured in the metadata document made available by Tyk Identity Broker.

FailureRedirect: Where to redirect failed login requests.

IDPMetaDataURL: The metadata URL of your IDP which will provide Tyk Identity Broker with information about the IDP such as EntityID, Endpoints (Single Sign On Service Endpoint, Single Logout Service Endpoint), its public X.509 cert, NameId Format, Organization info and Contact info. This metadata XML can be signed providing a public X.509 cert and the private key.

CertLocation: An X.509 certificate and the private key for signing your requests to the IDP, this should be one single file with the cert and key concatenated.

ForceAuthentication: Ignore any session held by the IDP and force re-login every request.

SAMLEmailClaim: Key for looking up the email claim in the SAML assertion form the IDP. Defaults to: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress

SAMLForenameClaim: Key for looking up the forename claim in the SAML assertion form the IDP. Defaults to: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/forename

SAMLSurnameClaim: Key for looking up the surname claim in the SAML assertion form the IDP. Defaults to: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname

Example profile configuration:

{
    "ActionType": "GenerateOrLoginUserProfile",
    "ID": "saml-sso-login",
    "OrgID": "{YOUR_ORGANISATION_ID}",
    "CustomEmailField": "",
    "IdentityHandlerConfig": {
        "DashboardCredential": "{DASHBOARD_USER_API_KEY}"
    },
    "ProviderConfig": {
        "SAMLBaseURL": "https://{HOST}",
        "FailureRedirect": "http://{DASHBOARD_HOST}:{PORT}/?fail=true",
        "IDPMetaDataURL": "{IDP_METADATA_URL}",
        "CertLocation": "myservice.cert",
        "ForceAuthentication": false,
        "SAMLEmailClaim": "",
        "SAMLForenameClaim": "",
        "SAMLSurnameClaim": ""
    },
    "ProviderName": "SAMLProvider",
    "ReturnURL": "http://{DASHBOARD_URL}:{PORT}/tap",
    "Type": "redirect"
}

Logging into the dashboard using SAML

In order to have dashboard access using SAML we need to create a TIB profile within our Tyk dashboard. You can find this under Identity Management on the left control pane. You can then select create profile, and use the raw editor to copy the example below:

{
    "ID": "saml-sso-dash-login",
    "OrgID": {ORG-ID},
    "ActionType": "GenerateOrLoginUserProfile",
    "Type": "redirect",
    "ProviderName": "SAMLProvider",
    "ProviderConfig" : {
        "CertLocation": {CERT-PATH-OR-ID},
        "SAMLBaseURL": {TIB-HOST},
        "ForceAuthentication": false,
        "FailureRedirect": "{DASH-HOST}/?fail=true",
        "IDPMetaDataURL": {METADATA-URL-PROVIDED-BY-IDP}
    },
    "IdentityHandlerConfig" : {
        "DashboardCredential" : "{DASH-CREDENTIAL}"
    },
    "ReturnURL" : "http://tyk-dashboard:3000/tap"
}

Logging into Tyk Portal using SAML

To obtain tyk portal access it's similar to the profile above, the minimum configuration to get this access is defined as the next profile:

{
    "ID": "saml-sso-dev-portal-login",
    "ActionType": "GenerateOrLoginDeveloperProfile",
    "OrgID": {ORG-ID},
    "ProviderConfig": {
        "SAMLBaseURL": {TIB-HOST},
        "FailureRedirect": "{PORTAL-HOST}/portal/login/",
        "IDPMetaDataURL": {METADATA-URL-PROVIDED-BY-IDP},
        "CertLocation": {CERT-PATH-OR-ID},
        "ForceAuthentication": true
    },
    "IdentityHandlerConfig": {
            "DashboardCredential": "{DASH-CREDENTIAL}"
    },
    "ProviderName": "SAMLProvider",
    "ReturnURL": {PORTAL-HOST}/sso/},
    "Type": "redirect"
}

Generating a Standard Auth Token using SAML

  {
        "ID": "saml-for-auth-api-token",
        "OrgID": {ORG-ID},
        "ActionType": "GenerateTemporaryAuthToken",
        "MatchedPolicyID": {POLICY-ID},
        "Type": "passthrough",
        "ProviderName": "SAMLProvider",
        "ProviderConfig": {
            "CertLocation": {CERT-PATH-OR-ID},
            "ForceAuthentication": false,
            "IDPMetaDataURL": {METADATA-URL-PROVIDED-BY-IDP},
            "SAMLBaseURL": {TIB-HOST}
        },
        "IdentityHandlerConfig": {
            "DashboardCredential": {DASH-CREDENTIAL},
            "TokenAuth":{
                "BaseAPIID": {API-ID}
            }
        }
    }

User Group ID Support

You can specify IDP User Groups within a TIB Profile. This can either be a static or dynamic setting. You will first need to create a matching group within the Tyk Dashboard to correspond to the group coming form the IDP. Use the id of the group created within Tyk to map it to the IDP group name. In the example below the "admin" and "analytics" are the group names being passed by the IDP and <admin-group-id> as well as <analytics-group-id> are the id from the groups you have already created in Tyk to correspond to the groups being passed.

If you wish to map users via email make sure you have "sso_enable_user_lookup": true, within your tyk_analytics.conf file.

{
  "DefaultUserGroupID": "<dashboard-user-group-id>",
  "CustomUserGroupField": "scope",
  "UserGroupMapping": {
    "admin": "<admin-group-id>",
    "analytics": "<analytics-group-id>"
  }
}

When doing SSO for a user, you need to think about the user's permissions once they are logged into the application. During the SSO flow of a user, TIB can request Tyk-Dashboard to login that user with certain user group permissions. In order to configure the user's permission you need to create a group in the Dashboard and use this group object ID as a value for these fields:

  • For a static setting set DefaultUserGroupID with a Dashboard group id. TIB will use it as the default user permissions when requesting a nonce from the dashboard. Note: If you don't set this field, the user will be logged in as an admin dashboard user.
  • For a dynamic setting based on OAuth/OpenID scope, use CustomUserGroupField with UserGroupMapping listing your User Groups names from the scopes to user group IDs in the dashboard, in the following format - "<user-group-name>": "<user-group-id>"

The Broker API

Tyk Identity Broker has a simple API to allow policies to be created, updated, removed and listed for programmatic and automated access. TIB also has a "flush" feature that enables you to flush the current configuration to disk for use when the client starts again.

TIB does not store profiles in shared store, so if you have multiple TIB instances, they need to be configured individually (for now), since we don't expect TIB stores to change often, this is acceptable.

List profiles

GET /api/profiles/
Authorization: test-secret

{
	"Status": "ok",
	"ID": "",
	"Data": [
		{
			"ActionType": "GenerateTemporaryAuthToken",
			"ID": "11",
			"IdentityHandlerConfig": {
				"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
				"DisableOneTokenPerAPI": false,
				"TokenAuth": {
					"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
				}
			},
			"MatchedPolicyID": "5654566b30c55e3904000003",
			"OrgID": "53ac07777cbb8c2d53000002",
			"ProviderConfig": {
				"ExrtactUserNameFromBasicAuthHeader": true,
				"OKCode": 200,
				"OKRegex": "origin",
				"OKResponse": "ewogICJvcmlnaW4iOiAiNjIuMjMyLjExNC4yNTAsIDE3OC42Mi4xMS42MiwgMTc4LjYyLjExLjYyIgp9Cg==",
				"TargetHost": "http://sharrow.tyk.io/ba-1/"
			},
			"ProviderConstraints": {
				"Domain": "",
				"Group": ""
			},
			"ProviderName": "ProxyProvider",
			"ReturnURL": "",
			"Type": "passthrough"
		},
		{
			"ActionType": "GenerateOAuthTokenForClient",
			"ID": "6",
			"IdentityHandlerConfig": {
				"DashboardCredential": "{DASHBAORD-API-ID}",
				"DisableOneTokenPerAPI": false,
				"OAuth": {
					"APIListenPath": "{API-LISTEN-PATH}",
					"BaseAPIID": "{BASE-API-ID}",
					"ClientId": "{TYK-OAUTH-CLIENT-ID}",
					"RedirectURI": "http://{APP-DOMAIN}:{PORT}/{AUTH-SUCCESS-PATH}",
					"ResponseType": "token",
					"Secret": "{TYK-OAUTH-CLIENT-SECRET}"
				}
			},
			"MatchedPolicyID": "POLICY-ID",
			"OrgID": "53ac07777cbb8c2d53000002",
			"ProviderConfig": {
				"FailureRedirect": "http://{APP-DOMAIN}:{PORT}/failure",
				"LDAPAttributes": [],
				"LDAPUseSSL": false,
				"LDAPPort": "389",
				"LDAPServer": "localhost",
				"LDAPUserDN": "cn=*USERNAME*,cn=dashboard,ou=Group,dc=ldap,dc=tyk-ldap-test,dc=com"
			}
			"ProviderName": "ADProvider",
			"ReturnURL": "",
			"Type": "passthrough"
		}
	]
}

Add profile

Request

POST /api/profiles/{id}
Authorization: test-secret

{
			"ActionType": "GenerateTemporaryAuthToken",
			"ID": "11",
			"IdentityHandlerConfig": {
				"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
				"DisableOneTokenPerAPI": false,
				"TokenAuth": {
					"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
				}
			},
			"MatchedPolicyID": "5654566b30c55e3904000003",
			"OrgID": "53ac07777cbb8c2d53000002",
			"ProviderConfig": {
				"ExrtactUserNameFromBasicAuthHeader": true,
				"OKCode": 200,
				"OKRegex": "origin",
				"OKResponse": "ewogICJvcmlnaW4iOiAiNjIuMjMyLjExNC4yNTAsIDE3OC42Mi4xMS42MiwgMTc4LjYyLjExLjYyIgp9Cg==",
				"TargetHost": "http://sharrow.tyk.io/ba-1/"
			},
			"ProviderConstraints": {
				"Domain": "",
				"Group": ""
			},
			"ProviderName": "ProxyProvider",
			"ReturnURL": "",
			"Type": "passthrough"
}

Response

{
	"Status": "ok",
	"ID": "11",
	"Data": {
		"ID": "11",
		"OrgID": "53ac07777cbb8c2d53000002",
		"ActionType": "GenerateTemporaryAuthToken",
		"MatchedPolicyID": "5654566b30c55e3904000003",
		"Type": "passthrough",
		"ProviderName": "ProxyProvider",
		"ProviderConfig": {
			"ExrtactUserNameFromBasicAuthHeader": true,
			"OKCode": 200,
			"OKRegex": "origin",
			"OKResponse": "ewogICJvcmlnaW4iOiAiNjIuMjMyLjExNC4yNTAsIDE3OC42Mi4xMS42MiwgMTc4LjYyLjExLjYyIgp9Cg==",
			"TargetHost": "http://sharrow.tyk.io/ba-1/"
		},
		"IdentityHandlerConfig": {
			"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
			"DisableOneTokenPerAPI": false,
			"TokenAuth": {
				"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
			}
		},
		"ProviderConstraints": {
			"Domain": "",
			"Group": ""
		},
		"ReturnURL": ""
	}
}

Update profile

Request

PUT /api/profiles/{id}
Authorization: test-secret

{
			"ActionType": "GenerateTemporaryAuthToken",
			"ID": "11",
			"IdentityHandlerConfig": {
				"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
				"DisableOneTokenPerAPI": false,
				"TokenAuth": {
					"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
				}
			},
			"MatchedPolicyID": "5654566b30c55e3904000003",
			"OrgID": "53ac07777cbb8c2d53000002",
			"ProviderConfig": {
				"ExrtactUserNameFromBasicAuthHeader": true,
				"OKCode": 200,
				"OKRegex": "origin",
				"OKResponse": "ewogICJvcmlnaW4iOiAiNjIuMjMyLjExNC4yNTAsIDE3OC42Mi4xMS42MiwgMTc4LjYyLjExLjYyIgp9Cg==",
				"TargetHost": "http://sharrow.tyk.io/ba-1/"
			},
			"ProviderConstraints": {
				"Domain": "",
				"Group": ""
			},
			"ProviderName": "ProxyProvider",
			"ReturnURL": "",
			"Type": "passthrough"
}

Response

{
	"Status": "ok",
	"ID": "11",
	"Data": {
		"ID": "11",
		"OrgID": "53ac07777cbb8c2d53000002",
		"ActionType": "GenerateTemporaryAuthToken",
		"MatchedPolicyID": "5654566b30c55e3904000003",
		"Type": "passthrough",
		"ProviderName": "ProxyProvider",
		"ProviderConfig": {
			"ExrtactUserNameFromBasicAuthHeader": true,
			"OKCode": 200,
			"OKRegex": "origin",
			"OKResponse": "ewogICJvcmlnaW4iOiAiNjIuMjMyLjExNC4yNTAsIDE3OC42Mi4xMS42MiwgMTc4LjYyLjExLjYyIgp9Cg==",
			"TargetHost": "http://sharrow.tyk.io/ba-1/"
		},
		"IdentityHandlerConfig": {
			"DashboardCredential": "822f2b1c75dc4a4a522944caa757976a",
			"DisableOneTokenPerAPI": false,
			"TokenAuth": {
				"BaseAPIID": "e1d21f942ec746ed416ab97fe1bf07e8"
			}
		},
		"ProviderConstraints": {
			"Domain": "",
			"Group": ""
		},
		"ReturnURL": ""
	}
}

Delete profile

Request

Delete /api/profiles/{id}
Authorization: test-secret

[empty body]

Response

{
	"Status": "ok",
	"ID": "200",
	"Data": {}
}

Save profiles to disk

Request

POST /Authorization: test-secret
[empty body]api/profiles/save

Response

{
	"Status": "ok",
	"ID": "",
	"Data": {}
}

Outcome:

The existing profiles.json file will be backed up to a new file, and a the current profiles data in memory will be flushed to disk as the new profiles.json file. Backups are time stamped (e.g. profiles_backup_1452677499.json).

tyk-identity-broker's People

Contributors

adelowo avatar alephnull avatar asutosh avatar batmanama avatar bmonteiro avatar buger avatar christtyk avatar deployinbinary avatar ermirizio avatar excieve avatar furkansenharputlu avatar gwotg avatar jbdrbs avatar jeffy-mathew avatar jlucktay avatar joshblakeley avatar komalsukhani avatar letzya avatar lonelycode avatar marksou avatar matiasinsaurralde avatar mativm02 avatar mcosta-tyk avatar rewsmith avatar saittalhanisanci avatar sedkis avatar sredxny avatar tbuchaillot avatar titpetric avatar tyk-its avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tyk-identity-broker's Issues

[Question] Seem to be getting 404 no matter what from tib

I'm trying to use the identity broker with the actiontype:"GenerateOAuthTokenForClient".

I have added the following profile in the profiles.json and it seems to load without issue (the number of profiles loaded when tib starts increased when I added it)

profiles.json:

{
    "ActionType": "GenerateOAuthTokenForClient",
    "ID": "3",
    "IdentityHandlerConfig": {
        "DashboardCredential": "{my dashboard credential}",
        "DisableOneTokenPerAPI": false,
        "OAuth": {
            "APIListenPath": "testtib",
            "BaseAPIID": "775a3ca552e241ce780c0a97b2a0b263",
            "ClientId": "7604a6f4cde541ee60f0478879a86377",
            "RedirectURI": "http://localhost:8000/final",
            "ResponseType": "token",
            "Secret": "NTFhOWFlZGEtN2Q5MC00MTA1LTc0M2MtMmUwNDI0YzcwZjcz"
        }
    },
    "MatchedPolicyID": "58b9865690f7a70001000003",
    "OrgID": "{org id}",
    "ProviderConfig": {
        "CallbackBaseURL": "http://localhost:3010",
        "FailureRedirect": "http://localhost:80/portal/login/?fail=true",
        "UseProviders": [{
            "Key": "{my google Client ID for Web application}",
            "Name": "gplus",
            "Secret": "{corresponding secret}"
        }]
    },
    "ProviderConstraints": {
        "Domain": "",
        "Group": ""
    },
    "ProviderName": "SocialProvider",
    "ReturnURL": "",
    "Type": "redirect"
}

TykDefinition.json oauth2 entries for the corresponding api:

"use_oauth2": true,
"oauth_meta": {
        "allowed_access_types": [
            "authorization_code"
        ],
        "allowed_authorize_types": [
            "token"
        ],
        "auth_login_redirect": "http://localhost:3010/"
    }

Now to this endpoint I am trying to post the following form bu no matter what I change the target to all I get are 404s.

<form role="form" method="POST" action="cc">
      <input type="hidden" class="form-control" id="response_type" name="response_type" value="token">
      <input type="hidden" class="form-control" id="client_id" name="client_id" value="aabf4d3602a64ebd67a528bd1ffbbbbf">
      <input type="hidden" class="form-control" id="redirect_uri" name="redirect_uri" value="http://localhost:8000/final">
    <button type="submit" class="btn btn-default">Start OAuth</button>
  </form>

I've tried and:
http://localhost:8080/testtib/oauth/authorize/
http://localhost:3010/testtib/oauth/authorize/
http://localhost:8080/testtib/oauth/authorize
http://localhost:3010/testtib/oauth/authorize

the page https://tyk.io/tyk-documentation/integrate/3rd-party-identity-providers/social-oauth/ seems to suggest that:
{listen_path}/toauth/authorize

So I've tried the same as above but with toauth instead of oauth in the url.

The image on https://tyk.io/tyk-documentation/concepts/tyk-components-2/identity-broker/

Seems to show the first request going directly to tib so I tried posting everything I could think of to the port tib usesbut everything produced 404s.

What am I doing wrong?

Add support of SalesForce Idp

In case of openId-connect provider, we use value of sub claim of /userInfo to set user Id. Value of user Id is then used to generate sso key.

But Salesforce provides URL in sub claim. This case is not handled currently.

LDAP Password

Hello,
So my openLDAP has password, and I don't see a field in profiles.json LDAP json configuration to add it. Is it possible to connect to a password-secured LDAP through Tyk Identity Broker?

README.md

Hi, I noticed that in some code examples, there are several "http://http://" entries, which I guess are not correct. It looks confusing to "newbies" like me ;-).

Ability to SSO to dev-portal using admin dashboard credentials

Is your feature request related to a problem? Please describe.
Currently while using TIB (standalone and embeded version) is not possible to SSO to dev portal using the admin-credentials (admin api), is possible to make it for dashboard access but not for dev-portal. The reason behind why is not possible is due the current flow, the steps are:

1- Consume Nonce API (admin in this case) and it's successful
2- Search the developer in the database using the dashboard api
3- If developer is not found then attempts to create the developer in database using standard api = this step fails as we try to consume this api using the admin credentials so we get 401 status code and the whole process fails

Describe the solution you'd like

  • Create an admin endpoint to register the developer

Describe alternatives you've considered

  • Detect if its the admin dashboard credential, if so then skip the step of register the developer and continue the whole flow

Additional context
I used this profile to replicate the issue:

{
  "ID": "ldap-for-sso-dev-portal",
  "OrgID": "5e2091c4d4aefce60c04fb92",
  "ActionType": "GenerateOrLoginDeveloperProfile",
  "MatchedPolicyID": "",
  "Type": "passthrough",
  "ProviderName": "ADProvider",
  "CustomEmailField": "",
  "CustomUserIDField": "",
  "ProviderConfig": {
    "FailureRedirect": "http://tyk-portal:3000/login",
    "LDAPAttributes": [],
    "LDAPPort": "389",
    "LDAPServer": "ldap.forumsys.com",
    "LDAPUserDN": "cn=*USERNAME*,dc=example,dc=com"
  },
  "IdentityHandlerConfig": {
    "DashboardCredential": "12345"
  },
  "ProviderConstraints": {
    "Domain": "",
    "Group": ""
  },
  "ReturnURL": "http://tyk-portal:3000/sso/",
  "DefaultUserGroupID": "",
  "CustomUserGroupField": "",
  "UserGroupMapping": {}
}

Redis backend settings issue

When using the followings settings, not all parameters under IdentityBackendSettings are read:

{
    "Secret": "test-secret",
    "HttpServerOptions": {
        "UseSSL": false,      
        "CertFile": "./certs/server.pem",
        "KeyFile": "./certs/server.key"
    },
	"BackEnd": {
		"Name": "redis",
        "ProfileBackendSettings": {},
		"IdentityBackendSettings": {
            "Hosts" : {
                "localhost": "6379"
            },
            "UseSSL": true,
            "SSLInsecureSkipVerify": true,
            "Password": "testpassword",
            "Database": 0,
            "EnableCluster": false,
            "MaxIdle": 1000,
            "MaxActive": 2000
        }
	},
	"TykAPISettings": {
        "GatewayConfig": {
            "Endpoint": "http://localhost",
            "Port": "80",
            "AdminSecret": "54321"
        },
        "DashboardConfig": {
            "Endpoint": "http://localhost",
            "Port": "3000",
            "AdminSecret": "12345"
        }
    }
}

The issue is that the IdentityBackendSettings data structure doesn't contain all of the fields (like UseSSL and SSLInsecureSkipVerify). This PR fixes the issue.

Create public packages for TIB

Create scripts to build the deb and rpm packages, as well as pushing them to packagecloud. This task should also include an internal continuous delivery pipeline for it.

Broken compatibility with 0.6 version

Looks like by introducing Dashboard level SSO API we broke compatibility with Admin API.
So after upgrade existing dashboard profiles stopped working until following section added to the profile:

"IdentityHandlerConfig": {
		"DashboardCredential": "ADVANCED-API-USER-API-TOKEN"
}

TT-5433 Log out from TIB should log out from identity provider

Is your feature request related to a problem? Please describe.
After logging into Tyk via an identity provider, if the user logs out of Tyk, they are not logged out of the identity provider. (They stay logged in.)

Describe the solution you'd like
Logout on Tyk should also log out from the identity provider

Additional context
Feature request from customer ticket 10237

LDAP provider based only on DN attribute

Hello,

It seems that LDAP provider is based on DN attribute only. It is possible to select additionnal filters but the initial search depends on DN attribute.

Would it be possible to use another attribute (sAMAccountName) ? In my organization, users' DN doesn't contain login, but first name and lastname. It also contains multiple OU.
Eg : CN=John Doe,OU=Unit1,OU=UnitB,DC=domain,DC=suffix
sAMAccountName = john.doe

I would like to be able to logon with "john.doe" as a login (instead of "John Doe"), and authorize users from different OU.

Did I miss something or does it require an enhancement ?
Thx

Using GET method in the form that send user/pass to ldap handler will cause failure on the 2nd login

Since the browser caches responses to GET the user will not be able to authenticate against the LDAP and the dashboard/dev portal will fail to log him in.

Reproduce:

           <form action="http://www.tyk-dashboard.com:3010/auth/ldap-portal/ldap">
                    <br/>
                    username: <input type="text" name="username"/> <br/>
                    password: <input type="text" name="password"/> <br/>
                    <input type="submit" value="login">
            </form>

log in, log out, log in again and see it doesn't work.

if you add POST method it will work:

       <form method="post" action="http://www.tyk-dashboard.com:3010/auth/ldap-portal/ldap">

TT-12175 Provider selection behavior change in >v1.1.1

Branch/Environment

  • Tag: >v1.1.1
  • Environment: Kubernetes

Describe the bug
After v1.1.1, attempting to access tib openid-connect provider fails with {"Status":"error","Error":"you must select a provider"}.

Reproduction steps
Steps to reproduce the behavior:
Profiles.json:

[{
  "ID": "keycloak",
  "OrgID": "<orgid>",
  "ActionType": "GenerateOrLoginUserProfile",
  "Type": "redirect",
  "ProviderName": "SocialProvider",
  "ProviderConfig": {
      "CallbackBaseURL": "https://tib.<domain>",
      "FailureRedirect": "https://tyk.<domain>/?fail=true",
      "UseProviders": [
      {
          "DiscoverURL": "https://keycloak.<domain>/auth/realms/<realm>/.well-known/openid-configuration",
          "Key": "<client_name>",
          "Name": "openid-connect",
          "Scopes": [
          "openid",
          "email"
          ],
          "Secret": "<secret>",
          "SkipUserInfoRequest": false
      }
      ]
  },
  "ReturnURL": "https://tyk.<domain>/tap",
  "SSOOnlyForRegisteredUsers": false
}]

Access url:
https://tib.<domain>/auth/keycloak/openid-connect

Actual behavior
I have a client configured in keycloak and accessing via the access url noted above works correctly (redirecting to keycloak and then back to tyk authenticated) on image version v1.1.1. On v1.2.1 and above (1.2.0 is just broken yielding exec format error and crashing on startup) this yields an error '{"Status":"error","Error":"you must select a provider"}'. My provider setup is as documented here.

Expected behavior
I'd expect provider selection to work as before, or documentation indicating the new pattern.

Additional context
Running in an EKS cluster. Tyk deployed with official helm charts: https://github.com/TykTechnologies/tyk-helm-chart/tree/master/tyk-pro v0.14.0, previously v0.13.2.

SkipUserInfoRequest not working

Branch/Environment

  • Branch: e.g. Master/v0.7.0
  • Environment: All

Describe the bug
The value SkipUserInfoRequest is not used correctly and the request to get the user information is triggered everytime, basically we can create a profile and set this value but later the method TAProvider.Init is not doing anything with it, and this value should be assigned to gProv.SkipUserInfoRequest in the Init method of the social Provider.

Reproduction steps
Steps to reproduce the behavior:

  1. Create a social provider for openid-connect
  2. Under ProviderConfig.UseProviders.SkipUserInfoRequest set the value to true
  3. Use the profile
  4. The request to get user info is being triggered even SkipUserInfoRequest is set to true

Actual behavior
The request to fetch user info is being triggered everytime

Expected behavior
The request to fetch user info should be triggered only when SkipUserInfoRequest is false.

Screenshots/Video
If applicable, add screenshots or video to help explain your problem.

Browser/Os (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Dashboard panics when settng up LDAP in Tyk Identity Broker

Branch/Environment

  • Branch: Master/3.0
  • Environment: On-prem

Describe the bug
When setting up LDAP, the UserID doesn't get properly populated, which causes a panic in the Dashboard:
ObjectIDs must be exactly 12 bytes long (got 0)
(Full panic log below, other examples in linked support tickets)

Reproduction steps
Steps to reproduce the behavior:

  1. Go to Identity Management
  2. Create a new profile using LDAP as the Provider
  3. Provider appropriate settings for LDAP
  4. See Dashboard panic

Actual behavior
Dashboard panics, LDAP doesn't work

Screenshots/Video
Panic log with user details removed:

Jul 16 11:11:45 api01svil tyk-identity-broker: time="2020-07-16T11:11:45+02:00" level=info msg="User bind successful" prefix="AD AUTH" username=g.xxxxx.mail
Jul 16 11:11:45 api01svil tyk-identity-broker: time="2020-07-16T11:11:45+02:00" level=info msg="Search: starting..." prefix="AD AUTH"
Jul 16 11:11:45 api01svil tyk-identity-broker: time="2020-07-16T11:11:45+02:00" level=info msg="Running LDAP search" DN="ou=users,o=xxxx" Filter="(&(uid=g.xxxxx.mail))" prefix="AD AUTH"
Jul 16 11:11:45 api01svil tyk-identity-broker: time="2020-07-16T11:11:45+02:00" level=info msg="User bind successful" prefix="AD AUTH" username=g.xxxxxx.mail
Jul 16 11:11:45 api01svil tyk-identity-broker: time="2020-07-16T11:11:45+02:00" level=info msg="Single Sign-On nonce created successfully via Dashboard API!" prefix="TYK_API"
Jul 16 11:11:45 api01svil tyk-analytics: time="Jul 16 11:11:45" level=error msg="Failure in user lookup: [email protected]. Error: 'not found'"
Jul 16 11:11:45 api01svil tyk-analytics: time="Jul 16 11:11:45" level=info msg="Created a new dashboard user. Logging using dashboard user." OrgId={ORG_ID_REMOVED} User's SSO Email="[email protected]"
Jul 16 11:11:45 api01svil tyk-analytics: time="Jul 16 11:11:45" level=error msg="Update failed for user"
Jul 16 11:11:45 api01svil tyk-analytics: time="Jul 16 11:11:45" level=error msg="ObjectIDs must be exactly 12 bytes long (got 0)"
Jul 16 11:11:45 api01svil tyk-analytics: time="Jul 16 11:11:45" level=error msg="Could not update LastLoginDate for dashboard user" userID="ObjectIdHex("")"
Jul 16 11:11:45 api01svil tyk-analytics: ERROR 2020/07/16 11:11:45.276451 panic_handler.go:26: PANIC
Jul 16 11:11:45 api01svil tyk-analytics: URL: /
Jul 16 11:11:45 api01svil tyk-analytics: ERROR: assignment to entry in nil map
Jul 16 11:11:45 api01svil tyk-analytics: STACK:
Jul 16 11:11:45 api01svil tyk-analytics: goroutine 656 [running]:
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.(*Router).handlePanic(0xc000666270, 0xc0003a9440, 0xc0003a9460, 0x15e2e60, 0x1ed50d0)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:277 +0x508
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.(*Router).ServeHTTP.func1(0xc000666270, 0xc0003a9440)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:43 +0x6f
Jul 16 11:11:45 api01svil tyk-analytics: panic(0x15e2e60, 0x1ed50d0)
Jul 16 11:11:45 api01svil tyk-analytics: /usr/local/go/src/runtime/panic.go:522 +0x1b5
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.(*User).Permissions(0xc000a8e6c0, 0x0, 0x0, 0x0)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/model_user.go:168 +0x33c
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.(*Context).createViewAllowance(0xc000010378, 0xc0000103a8, 0x180c376)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/api_context_methods.go:126 +0x51
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.(*Context).ShowIndex(0xc000010378, 0x1f31dc0, 0xc0003a9440, 0xc0003a9460)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/api_context_methods.go:410 +0x114e
Jul 16 11:11:45 api01svil tyk-analytics: reflect.Value.call(0x1592760, 0x1b7d7d0, 0x13, 0x17fe905, 0x4, 0xc0001b1fe0, 0x3, 0x3, 0x0, 0xc0001b1e98, ...)
Jul 16 11:11:45 api01svil tyk-analytics: /usr/local/go/src/reflect/value.go:447 +0x461
Jul 16 11:11:45 api01svil tyk-analytics: reflect.Value.Call(0x1592760, 0x1b7d7d0, 0x13, 0xc0001b1fe0, 0x3, 0x3, 0xc00034cf40, 0x20, 0x40)
Jul 16 11:11:45 api01svil tyk-analytics: /usr/local/go/src/reflect/value.go:308 +0xa4
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.middlewareStack.func1(0x1f31dc0, 0xc0003a9440, 0xc0003a9460)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:139 +0x396
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.GoCraftHttphandlerFunc.func1(0x1f11a60, 0xc0003a9440, 0xc000caa800)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/server.go:620 +0x40
Jul 16 11:11:45 api01svil tyk-analytics: net/http.HandlerFunc.ServeHTTP(0xc0004b4e70, 0x1f11a60, 0xc0003a9440, 0xc000caa800)
Jul 16 11:11:45 api01svil tyk-analytics: /usr/local/go/src/net/http/server.go:1995 +0x44
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/TykTechnologies/nosurf.(*CSRFHandler).handleSuccess(...)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/TykTechnologies/nosurf/handler.go:180
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/TykTechnologies/nosurf.(*CSRFHandler).ServeHTTP(0xc0001b22b0, 0x1f11a60, 0xc0003a9440, 0xc000caa800)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/TykTechnologies/nosurf/handler.go:137 +0x587
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.CSRFMiddleware(0x1f31dc0, 0xc0003a9440, 0xc0003a9460, 0xc0003f8810)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/server.go:641 +0x2e9
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.(*middlewareHandler).invoke(0xc000694540, 0x17601e0, 0xc000010378, 0x16, 0x1f31dc0, 0xc0003a9440, 0xc0003a9460, 0xc0003f8810)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:157 +0x374
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.middlewareStack.func1(0x1f31dc0, 0xc0003a9440, 0xc0003a9460)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:148 +0x17f
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/dashboard.DisableCacheMiddleware(0x1f31dc0, 0xc0003a9440, 0xc0003a9460, 0xc0003f8810)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/dashboard/server.go:665 +0xa00
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.(*middlewareHandler).invoke(0xc000663ec0, 0x17601e0, 0xc000010378, 0x16, 0x1f31dc0, 0xc0003a9440, 0xc0003a9460, 0xc0003f8810)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:157 +0x374
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web.middlewareStack.func1(0x1f31dc0, 0xc0003a9440, 0xc0003a9460)
Jul 16 11:11:45 api01svil tyk-analytics: /src/github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/web/router_serve.go:148 +0x17f
Jul 16 11:11:45 api01svil tyk-analytics: github.com/TykTechnologies/tyk-analytics/vendor/github.com/gocraft/

Additional context
Reported by customers in tickets 10849, 10879, and 10890

Basic Auth against LDAP integration

My use case is as follows:

a) User sends an API request w/ a basic-auth header to an exposed API on a gateway

b) I need to take that basic auth uname/pw and validate it against ldap

c) Return a 401 on authn fail, otherwise let the request proceeed

Please correct me if I am wrong, but the identity broker as I understand it, is not really a solution for this scenario? It seems to be more of just an AUTHN backend for existing token based flows, with the auth request being requested against the id broker, not just a gateway API. (per this diagram: https://tyk.io/docs/concepts/tyk-components/identity-broker/)

I need some sort of middleware hook that can do this against ldap, I don't see anything out of the box in Tyk which just supports this. (other than the IDP support for LDAP for securing the dashboard/portal only, but not just a user-defined API the gateways serve up)

Reporting Vulnerability

Hello!

I hope you are doing well!

We are a security research team. Our tool automatically detected a vulnerability in this repository. We want to disclose it responsibly. GitHub has a feature called Private vulnerability reporting, which enables security research to privately disclose a vulnerability. Unfortunately, it is not enabled for this repository.

Can you enable it, so that we can report it?

Thanks in advance!

PS: you can read about how to enable private vulnerability reporting here: https://docs.github.com/en/code-security/security-advisories/repository-security-advisories/configuring-private-vulnerability-reporting-for-a-repository

Don't panic if ProviderName is unknown

Yesterday I had to support a customer who was trying to make use of openidconnect but had a misconfiguration in the value of ProviderName and his log was filled with stack traces.

[ {
    "ActionType": "GenerateOrLoginDeveloperProfile",
    "ID": "1",
    "IdentityHandlerConfig": {
      "DashboardCredential": "6b7358686cb846f17cba6abc7af72d5d"
    },
    "OrgID": "5ca2f0f116e579998237d464",
    "ProviderConfig": {
      "CallbackBaseURL": "http://lanre.tyk.io:3010",
      "FailureRedirect": "http://lanre.tyk.io:3000/portal/login/",
      "UseProviders": [
        {
          "Name": "twitter",
          "Key": "xVvepjKmJclqrNq1F4W5O3G6P",
          "Secret": "dZOQeNvvCUFLdXI8WQ606ocLMgrGwpkz4wxtdtqNmQYp32a5pb"
        }
      ]
    },
    "ProviderName": "salesforce",
    "ReturnURL": "http://{HOST}:{PORT}/tap",
    "Type": "redirect"
  }

Panic log -- https://gist.github.com/adelowo/c6b2ba4272756df34bda22bf5e3f673b

We have two options here :

  • Validate that field while loading the configuration and skip if an invalid provider name is used
  • Or return an error that similar to what is displayed when UseProvider[index].Name is unknown
{"Status":"error","Error":"no provider for xyz exists"}

Critical security vulnerabilities in TIB docker image

Is your feature request related to a problem? Please describe.
We run an image vulnerability scan in our Kubernetes cluster and found out that there are a couple of critical vulnerabilities present in the TIB(0.7.1) image

Describe the solution you'd like
Normally we would prefer if the image is free of any critical vulnerability, when I dig deep into this we realized that these are not brought in by tyk but debian:slim-buster base image, and when I build the image again those vulnerabilities are gone because the same has been fixed and upgrade commands updates the vulnerable dependencies
I have seen many projects build their releases multiple times a day to make sure everything is in sync with the upstreams and bugs and security fixes are being pulled in from the upstream, if we can have a pipeline that builds once a day that should suffice the need

If this doesn't work we can always build the images ourselves and use that

The tool used for scanning: Trivy

Panic thrown when attempting to create SSO request without sufficient configuration

Branch/Environment

  • Branch: master (34d1bf5)
  • Environment: Ara dev environment

Describe the bug
Panics are being thrown in the SSO process when there is some invalid Dashboard config set.

Reproduction steps

  1. Set empty/bogus configuration under TykApi.DashboardConfig
  2. Launch TIB
  3. Hit the /admin/sso endpoint

Actual behaviour
TIB panics.

Expected behaviour
This section should return a clear error if creating the request returns an error:

newRequest, err := http.NewRequest(method, preparedEndpoint, body)
if err != nil {
tykAPILogger.Error("Failed to create request")
tykAPILogger.Error(err)
}

Screenshots/Video

Browser/Os (please complete the following information):

Additional context
Related to an issue occurring in Ara & Tyk Dashboard.

Improve DX - TIB should return the URL you need to use to SSO

You can compose the URL yourself from the profile id and UseProviders.name but it would be **clearer, easier and cause fewer errors ** if TIB can just return it in another endpoint or a field

http://{DASH_HOSTNAME}:{DASH_PORT}/auth/{PROFILE_ID}/{UseProviders.name}

Allow configure scopes for OpenID plugin

At the moment TIB always makes the request only with "openid" scope, however, in some cases OpenID server may forbid return things like "email" without a specific scope.

It should be possible to set additional scopes for OpenID provider.

Tyk identity broker start fails with defaults

Branch/Environment

  • Branch: Master
  • Environment: On-prem

Describe the bug
In the latest release(1.2.0), the default docker command to run the image fails

Reproduction steps
Steps to reproduce the behavior:

  1. Run command docker run -p 3010:3010 -v $(pwd)/tib.conf:/opt/tyk-identity-broker/tib.conf -v $(pwd)/profiles.json:/opt/tyk-identity-broker/profiles.json tykio/tyk-identity-broker:v1.2.0
  2. This throws an error and the container doesn't start

Actual behavior
flag provided but not defined: -conf
Usage of /opt/tyk-identity-broker/tyk-identity-broker:
-c string
Path to the config file (default "tib.conf")
-p string
Path to the profiles file (default "./profiles.json")

Expected behavior
The container should have started without error

Additional context
If we change the command to docker run -p 3010:3010 -v $(pwd)/tib.conf:/opt/tyk-identity-broker/tib.conf -v $(pwd)/profiles.json:/opt/tyk-identity-broker/profiles.json tykio/tyk-identity-broker:v1.2.0 -c /opt/tyk-identity-broker/tyk-identity-broker.conf then everything works fine

Check that the dashboard's credentials were set in Profiles.json before using it

A certain profile in Profiles.json should contain a user's api key with apropriate credentials in DashboardCredential field as follows:
...
{
"ActionType": "GenerateOrLoginDeveloperProfile",
"ID": "okta-portal-sso",
"IdentityHandlerConfig": {
"DashboardCredential": "1e8dd588ac0a40827c47eb53997bb1ae"
},
....
}

We need to verify that the value is not empty before making an api call to the dashboard, or even during startup/profile creation or update, so the admin would know it and get the error before the user does.
BTW, We don't need the creds in case of dashboards sso, i.e. "GenerateOrLoginUserProfile", since we only use admin creds for it ( if will change the /sso endpoint to be a regular dashboard endpoint then we would need it here as well).

tyk_handler responses are mixed between application/json and text/plain

When trying to authenticate using a ProxyProvider for token auth for example, if you do not use a ReturnURL, a positive response will return JSON like so:

{ "key_id": "12345" }

However any failure response will return plaintext like so:

"Data Failure"
"Auth token generation failed"
"Login failed"

The same holds true for OAuth authentication when using NoRedirect.

This puts extra burden on login code as it must handle both JSON and plaintext responses from the same API call.

It would definitely be preferable if we could send over an 'Accept: application/json' header to get all responses back in JSON format

[TT-2527] SAML flow cached in different profiles

Hi @letzya , @joshblakeley

Using version 1.1.1 because the v1.2.0 it is not working in k8s because of the #168

The below image shows it well but still a small explanation:

  • Trigger the SSO flow with TIB using the URL https:///auth/devportal/saml that will lookup the profile ID "devportal" and take it from there to SSO in the DevPortal (profile config below)

If the above is the 1st call after starting the application in k8s all other consequent calls will SSO in the DevPortal even if it is using another profile with SAML configuration.

For example:
Trigger the SSO flow using the URL https:///auth/dash/saml should lookup the profile ID "dash" and take it from there to SSO in the Dashboard (profile config below) this is not happening because it is redirected to DevPortal again (image below)

.. ====>>> tib-tyk-tib-tyk-pro-tib-64fcffbd77-86mzz tib-tyk-pro-tib time="May 20 10:14:31" level=debug msg="--> Looking up profile ID: dash" prefix="AUTH HANDLERS" tib-tyk-tib-tyk-pro-tib-64fcffbd77-86mzz tib-tyk-pro-tib time="May 20 10:14:31" level=debug msg="Binding: urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" prefix="SAML AUTH" tib-tyk-tib-tyk-pro-tib-64fcffbd77-86mzz tib-tyk-pro-tib time="May 20 10:14:31" level=debug msg="BindingLocation: https://login.microsoftonline.com/cd203e99-2c5a-4f80-ab44-ee15c03df09c/saml2" prefix="SAML AUTH" ====>>> tib-tyk-tib-tyk-pro-tib-64fcffbd77-86mzz tib-tyk-pro-tib time="May 20 10:14:40" level=debug msg="--> Looking up profile ID: devportal" prefix="AUTH HANDLERS" ...

Profiles config:
{ "ActionType": "GenerateOrLoginUserProfile", "ID": "dash", "OrgID": "XXX", "CustomEmailField": "", "ProviderConfig": { "SAMLBaseURL": "https://<URL>", "FailureRedirect": "https://<DASH URL>/?fail=true", "IDPMetaDataURL": "https://login.microsoftonline.com/cd203e99-2c5a-4f80-ab44-ee15c03df09c/federationmetadata/2007-06/federationmetadata.xml?appid=14ce9a50-eb95-4bf3-bf1f-0fdb2d2490f4", "CertLocation":"/tmp/cert-saml.crt", "ForceAuthentication": true, "SAMLEmailClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "SAMLForenameClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", "SAMLSurnameClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" }, "ProviderName": "SAMLProvider", "Type": "redirect", "ReturnURL": "https://<DASH URL>/tap", "CustomUserGroupField": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "UserGroupMapping": { "93b817d0-3b41-4730-a4cd-180eb56cff1b": "60a4347f5fd85e0001b0e225" } }, { "ActionType": "GenerateOrLoginDeveloperProfile", "ID": "devportal", "OrgID": "XXX", "CustomEmailField": "", "IdentityHandlerConfig": { "DashboardCredential": "XXX" }, "ProviderConfig": { "SAMLBaseURL": "https://<URL>", "FailureRedirect": "https://<DEVPORTAL URL>/login", "IDPMetaDataURL": "https://login.microsoftonline.com/cd203e99-2c5a-4f80-ab44-ee15c03df09c/federationmetadata/2007-06/federationmetadata.xml?appid=bc7b1fba-0d14-4045-aa00-e7cb2bd365f0", "CertLocation":"/tmp/cert-saml.crt", "ForceAuthentication": true, "SAMLEmailClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", "SAMLForenameClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", "SAMLSurnameClaim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" }, "ProviderName": "SAMLProvider", "Type": "redirect", "ReturnURL": "https:/<DEVPORTAL URL>/sso" },

image

Add way to ignore OpenID introspection endpoint

Some IDP return information about the user inside the ID token, but do not properly support userinfo endpoint. For example ADFS.
In the case, if userinfo does not work, it stops using values from ID token, and field like email gets blank.

By checking the source of the library it has a flag to ignore calling the userinfo endpoint but it is not exposed to our configuration.

CustomEmailField Dashboard SSO not working

Customer TIB Dashboard SSO (oidc) not working as expected, resulting in user being logged into the Dashboard as the default [email protected] user. The customer's ADFS openid provider (ADFS) does not support /userinfo and does not return an email claim. In the id_token returned from ADFS, there is a upn claim which contains an email address, so assumed that setting CustomEmailField would result in the upn claim being used for email.

I have reproduced this issue using Okta IdP. I configured Okta to return a custom claim secondemail and in my TIB profile I set "CustomEmailField": "secondemail". I see in the logs this custom claim is being returned by Okta, but instead of being logged in as the email address contained in the secondemail claim, I am logged in as [email protected]

andy-TIBlog.txt

profiles-okta.json.zip

I should be able redirected to the api when using GenerateOAuthTokenForClient

TIB should be able to redirect the call to the target api instead of the user writing code to grab the access token and inject it to a separate api call. Many clients would be happy to avoid that.

We can add the api id as a query param to the first call we make to tib and in the profile, we can add a list of headers and query params required for the api call.

Add a generic OAuth handler

The OAuth handlers currently are all specific to a provider, it should be possible to provide a generic handler that TIB can point at any OAuth provider to generate a login or token

Maintain consistency in Logger when its set by external app

As now TIB can be used as a library by external applications and it allows to set a logger (the logger of the main app) we need to ensure to maintain the same format in:

  • Dates
  • Log Level
  • Colors

Therefore, when this logger is set we need to reload or directly set the updated version of the logger in each of the packages that compound tyk-identity-broker. Take in consideration that we need to maintain as well consistency in the logs level displayed, it means that if dashboard is in Debug Log Level, then all the debug logs of TIB should be printed as well, is not only format of information

This ticket is subtask of https://github.com/TykTechnologies/product/issues/241

Pull Requests Information
These 2 PR's should be merged in tandem, as Tyk-Analytics use a function of TIB added in its respective PR. The Pr's are:

#96
TykTechnologies/tyk-analytics#1884

Add support for DB storage backend of profiles

Currently there's no way to configure a profile backend other than in-memory storage. In addition to this TIB writes profiles to a local file. This doesn't work well in setups where profiles are created and modified using TIB API rather than providing a profiles.json file with everything pre-set.

One notable example of "not working well" is Kubernetes, where filesystem is by default ephemeral, persistent volume claims not available on every infrastructure and where available can't be written by multiple instances without a distributed FS, hence no fail-over possible and overcomplicates the deployment anyway.

It should be possible to configure an external DB as a backend for profiles storage instead of the file. There should be support for multiple DBs eventually, but can start with MongoDB. Another option could be Redis (there's already a backend for identity handlers), but it's not always persistent.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.