A "Location" is a part of the site which matches specific attributes in the incoming request - it can be e.g. a specific hostname (virtual host), it can be based upon URL path, or even user ID or group.

For a particular location you specify how the gateway should react - should it modify the request or responses ? should it add /  remove headers or cookies, and should it forward/proxy the request to one of the configured Destinations or should it respond with a specific response or a dynamic one created by a script.

Locations can be nested, so you can have a setup similar to this:

In this example, the first location matches every request - and it just adds a Via: HTTP header to the response - the next location matches any request where the hostname matches the pattern app.* - this location does not need to do anything itself (although it can) - and once that is done, any eventual nested locations get a chance to look further at the request - in this case we have an anonymous part of the site, and a secret part, which requires specific group membership to be able to access. If neither the anonymous or the secret part is hit, the default action is to respond with an error.

Location Processing

Each configured location is processed in order, starting with the top one and going down the chain - if the specified conditions match, any eventual nested locations are processed before moving down the train.

Each location has an action, and processing terminates when a matched location results in either the Proxy or Respond action - meaning the location either proxies the request onwards to one of the configured Destinations or it responds with a specified or scripted HTTP response.
Actions can be one of continueproxyrespond or serve

Location Flags

A location has a few flags that can be set;

Limits / Request Throttling

You can limit the number of concurrent requests, and/or the number of requests per second.

Limits can be qualified using macros, e.g. %{REMOTE_ADDR} limits concurrent requests or requests per second per IP address while %{statevariable:client_id} limits requests for a specific client_id state variable taken from the session.
Note that limits are per location, so limits per client ID for one location does not affect other locations. 

These limits are used for throttling requests - they are not denying requests if limits are exceeded. Requests are queued up unless the queue size has been exceeded.

If you want strict limits and want to deny requests if they exceed the limits, perhaps rate limiting, subscriptions etc. in the API Management will do the trick for you, please see API Management Configuration.

Any limitations are set per Gateway instance - so if you have multiple gateways running and need fixed total limits, you need to adjust your limits accordingly for each gateway.


The limits are configured using fixed number of requests per seconds - this means you cannot directly specify a limit of 10 requests for one client_id and a limit of 20 requests per second for another client_id, but you can archive this by splitting into different groups.

Imagine you have 3 different sets of Quality Of Service (QOS) type of limits you want to configure - one for basic customers, another for gold members and a 3rd for platinum members.

You can archive this by setting a Request Attribute, e.g. "rategroup" (using either a script, macro, pipeline etc.) - and after this is set, you can define 3 locations;

  • "Rate limiting basic" where you set the rate limit to 10 requests per second, and in the conditions for this location, set request attribute rategroup=basic
  • "Rate limiting gold" where you set the rate limit to 100 requests per second, and in the conditions, set the request attribute rategroup=gold
  • "Rate limiting platinum" where you set the rate limit to 1000 requests per second, and in the conditions, set the request attribute rategroup=platinum

This allows you to divide your requests into multiple groups with limits set according to the group.


Conditions

Conditions are the rules for selecting a specific location - locations are processed one at a time, top-down - any eventual nested/child locations are processed before further requests in the chain - but only if the "parent's" conditions matched the request.

Conditions can be defined on the following attributes;

Multiple different values can be configured for each attribute, and you can negate the expression, e.g. the condition can be matched if the attribute does NOT match a configured value.

Also, in the individual value string you can use wildcards; * and ? or the pipe sign | to specify multiple values.
you can also prefix it with {uripath} - in this mode, * will match any character except for the forward slash /. If you prefix it with {regex} then you can specify a regular expression.
When using{regex} you can optionally specify flags for regular expression matching, e.g. {regex:IGNORE_CASE} - the flags available are:

Please refer to Oracle's Java documentation for the individual flags and their meaning here: https://docs.oracle.com/javase/tutorial/essential/regex/pattern.html 


Conditions are very powerful - as an example, if you configure an IP range and set it up to load data periodically from an IP reputation database, you can set up a location with a condition where the remoteip matches the IP range.

Then you can take action on the request originating from a known spammer, tor exit node, anonymizer, malware spreader, attacker or spammer.

Action could include:

  • Denying all traffic from known "bad" clients
  • Limiting concurrent requests or requests per second, scaling down service provided to known bad addresses.
  • Require additional authentication, e.g. two-factor before accepting requests.


Invalid Session Action

If a session is invalid, e.g. a session cookie contains a session that is timed out, you can respond with an error message, redirect to another URL or you can continue on with a new anonymous session.

The "Invalid Session Action" controls what to do in which case.

Nested Locations

Locations can be nested, so if a match is found for this location, and its action is "continue" then processing will continue with any matching nested sessions that might exist.

Response Hooks

Response hooks allow you to easily hook into specific HTTP responses and change them or do something specific based upon then - e.g. instead of sending a 401 response back, you can redirect to a login page.
You can also change the HTTP status code or modify HTTP headers before they are being processed by the gateway.

URL Validation

The incoming request URL can be validated both for correct encoding and for valid characters as well as maximum lengths of either the complete URL or any individual query parameters.
Additionally, hostname and domain can optionally be validated to ensure it is correct according to IANA verified top-level domains.

Parameter Validation

Allows you to validate path, query and POST parameters in the request - you can specify valid key / name patterns and valid value patterns and regular expressions to validate all input parameters.
In case validation fails, you can specify what action to take, such as returning an error message.
You can use this to defend against e.g SQL Injection attacks by limiting the acceptable input characters. 

URL Rewrite

URLs can be rewritten before processing is continuing with the rewritten URL - both scheme, hostname and path can be changed.
When rewriting URLs, you can use regular expressions, and e.g. rewrite from ^/TOPSECRET/(.*) to /secret/$1 - this will change an incoming URL /TOPSECRET/sample to /secret/sample. You can also apply specific conditions to each URL Rewrite expression so it is only done in case the listed conditions match.

IP Change Restriction

By default, clients are not allowed to change IP address during their session, this means that the requests will fail if the user changes IP address mid-session. But, you can allow this (for individual or all locations) either by using GeoIP location information, and e.g. allow clients to change IP address within the same country, same ISP or same city or even with a given distance to the original IP.
You can also define complex matching rules, where you e.g. allow change of country between specific known countries, e.g. Denmark and Sweden, or you can define a script which can determine if it allows the change or not based upon full request and session content.

In addition to using GeoIP you can specify a number of ranges where IP switching is allowed within a range - e.g. any IPs within the 192.168.1.0/30 range.

Note that IP checking is only done for a location if a session is available - if the "Session is needed" flag is turned off, no validation is done, since no original IP address is known. If you want to protect a location so it is only available for a specific set of IP addresses, consider using IP restrictions in location instead of IP Change Restriction instead.

Authentication

For each location, you can specify a form of Authentication that is supported - for each authentication type, you can specify if it is required or not, and what to do if that particular sort of authentication information is not provided.

Ceptor Gateway is currently provided with the following Authentication Plugins; (see the Plugins section for additional information).

Typically, you use the Gateway for transport-level authentication, and use either Forms authentication or another Location to redirect to a Destination Server which is reachable anonymously - in that, you can provide advanced authentication dialog with the user, e.g. for NemID Login, or Two-Factor authentication - the application then has the dialog with the user until he is authenticated and redirects back to the original location when authentication has completed.

Authorization

You can configure the Gateway to do Authorization checking for a given location - in here, you can specify the list of valid HTTP methods. You can specify a list of one or more roles where at least one of them are required for the user to have access. You can use the following magic role names;

You can also specify a server identifier - if done, the configured Authorization plugins in the Ceptor Session Controller will be called - they can provide a list of protected URLs for a given server identifier, and the URLs will be checked against this list also.

Lastly, you can specify a script to run to do more detailed authorization checking based upon all information in the request and the session, as an example this scripts denies access if the Content-Type header in the request contains the string "YouShallNotPass" but allows access otherwise.

if (state.httpExchange.getRequestHeaders().getFirst('Content-Type') == 'YouShallNotPass')
  false;
else
  true;

Note that to gain authorization, all defines checks has to pass, meaning both the listed roles / groups, the URLs from the authorization plugin, and the script must all allow authorization or it will fail. For failed authorization checks, you can specify what to happen, e.g. redirect to another URL, send back an error page or JSON error structure based upon the request Accept header.

Request Attributes

A location can set request attributes which can be used within conditions by other locations, or they can be accessed by scripts that are run later in the request processing flow. The value of each individual attribute can be set to either a macro or a script.

Request Headers

You can specify a list of HTTP headers that are added to the request before processing continues. Refer to Scripts and Macros for information on the possibilities on how to specify values as scripts and/or macros.

Any value that results in an empty string, or a script that returns null means that the header will be removed from the request.

By combining this with Location Conditions, you could e.g. create a location which in its condition has a group called pp_identifiedusers - this means that it will be processed for all identified users. In this Location, you can leave the action as "continue", and add the Request Header "AuthenticatedUser" with the value "%{REMOTE_USER}", and another header called "AuthenticatedGroups" with the value "%{SESSION_GROUPS}".

This will then add two HTTP headers to any requests later being proxied to a Destination; AuthenticatedUser and AuthenticatedGroups with respectively the userid and a comma-separated list of usergroups.

Request Cookies

Like with specifying HTTP request headers, you can add request cookies to the request here - here, you can e.g. delete the sessionid / sslsessionid cookies that contained the original session ID if you do not want to proxy this on to Destinations or you can add other cookies and values based upon request or session content.

Response Headers

You can specify a list of HTTP headers that are added to the response when it is sent back to the client. Refer to Scripts and Macros for information on the possibilities on how to specify values as scripts and / or macros.

Response Cookies

You can specify a list of reply cookies that are added to the response when it is sent back to the client. Refer to Scripts and Macros for information on the possibilities on how to specify values as scripts and / or macros.
This feature can also be used to modify existing cookies, e.g. to add httpOnly / secure flag, path or domain to them.

Note that while rules for request headers are processed sequentially starting with the first location, the sequence is reversed for response headers and cookies, so if you have locations A, B and C, and each has rewrite rules for both request and response headers, request headers will be processed in sequence A, B, C while response headers and cookies will be processed as C, B, A.

Canned Responses

Canned Responses are responses that can be defined and reused from multiple different locations - where you reuse it, you can override specific parts of the response, such as status code, reason or HTTP headers.

WebServer

If action is set to serve then the gateway can serve static resources, e.g. images, stylesheets, javascript or html files. This allows you to reference static resources from responses, e.g. error pages and serve them directly for the gateway.