How a requests flows through Ceptor

The following article explains how a request flows through the typical parts of Ceptor, what happens where and how authentication and authorization takes place.

High Level Overview

Imagine the following setup:

Here, a client wants to call an application - it does that by calling the Ceptor Gateway which is a reverse proxy that all requests travel through. Ceptor gateway then typically starts by establishing a session if not already present, and then examines the request information - it looks at attributes like hostname, URL Path and/or query parameters - based upon these attributes, and the configuration of the gateway, it selects a destination to transmit the request to.

After this, it looks at its configuration to check if the client has access to the particular resource or not - it might need to authenticate the client as part of this process.

If authentication is needed, it is done by calling a module within Ceptor Server, specifically the Ceptor Session Controller where all authentication is done.

After any authentication and authorization is done, the request is then typically proxied to the application server, and the reply is streamed back to the client - any future requests go through the same process.

Inside the destination server, an optional Ceptor Agent or Application Server Plugin might do more fine-grained authorization checking.

Inside the Gateway

Digging one step deeper, by looking into the Ceptor Gateway and seeing what steps it performs.

For a lot of background on how the gateway works and the terminology and functionality within it, please read Gateway Concepts

Inside the gateway, a number of steps are performed, the actual steps vary, but typically it is similar to this:

Listener

Requests are received via a Listener - the listener listens for incoming requests using one of the protocols HTTP, HTTPS or AJP - the configuration for the listener also decides SSL/TLS settings, and decides if the user should be prompted for a client certificate. A gateway can have multiple different listeners on any combination of IP address and port.

Process Locations

Once a request is received processing of it starts - the gateway has a Hierarchical tree of "Locations" 

See more conceptual information about Locations here: Locations and more about the configuration options for a location here: Config - Locations

Processing starts with the first location, then if it matches any child locations are processed, otherwise the next location in the tree is processed. This all continues until a location sends back a response, proxies the request to an application server, serves an API or in other ways produces a response.

The order that a particular location is processed in corresponds closely to what you can see in the Ceptor ConsoleGateway Configuration - meaning the order of the items you see is the same order that the location is processed in.

Flags, conditions and sessions

First, the Gateway check the location flags, to see if the particular location is enabled or not, if a session is needed, if the conditions match etc.

If a session is needed, then one or more Session Resolvers are invoked in order to establish a session - the Session Resolvers are invoked in order until one of the produces a valid session. This session can originate from e.g. a session cookie or an API key or bearer token or any other attribute available in the incoming request such as the value of an HTTP header, an SSL client certificate etc..

All this is cached by the Ceptor Agent embedded inside the Gateway, so resolving a session rarely involves a remote call - actually only in case it is no longer cached by the agent which happens every 5 minutes or when its content is changed by any other module or API.

You can find more details about sessions here: Sessions

Once the session is identified (or established by creating it), the conditions are checked. Note that establishing the session might be postponed until after the conditions are checked depending on the flags set on the location - but some conditions (such as checking for userid or group or attributes within the session) require that a session is established first before the condition can be checked.

In case the configured conditions for a Location matches, processing of that location begins...

Processing starts with checking eventual Limits / Request Throttling, running scripts and eventual pipelines (see Pipelines and Tasks) and continues onwards with URL validation, parameter validation, eventual URL rewriting, IP address restriction checking etc. - continues with Authentication and Authorization and finally adds or changes request headers and cookies and/or response headers and cookies.

Response headers and cookies are not actually processed at this particular point in time, but rather queued up for later processing once a reply is about to be sent back to the client.

Authenticate Client

If a location has any Authentication plugins specified, they are called in order to authenticate the client - it is up to the individual plugin what to do in case the user is already authenticated - most plugins will skip authentication, but they have the option to re-authenticate.

See Location - Authentication for details about the available Authentication Plugins inside Ceptor Gateway and the configuration of them. For developing your own Authentication plugins, see Plugins or get more info on writing them in Scripts here: Scripts and Macros

If authentication is done, the gateway authentication plugins do this by calling Ceptor Agent API which in turn calls Ceptor Session Controller - the session controller will load and run one if its configured authentication plugins to complete the request and authenticate the client using the provided credentials.

Do not confuse the authentication plugins in the Ceptor Gateway with the authentication plugins inside the Ceptor Session Controller.

The plugins in the gateway are responsible for obtaining information, credentials etc. from the incoming request and making a remote call to the Session Controller to authenticate the session with the provide credentials.

The plugins inside the Session Controller are responsible for authenticating the user using the provided credentials - in other words, to fill the session with information about the client/user and his or her permissions and attributes.

The Session Controller and its Authentication Plugins does NOT have access to the HTTP request, since its plugins might be invoked not just by the Gateway, but by other components, such as Ceptor RADIUS Server or Ceptor Agent on behalf of other types of non-HTTP clients.

Perform Authorization

Once any eventual authentication plugins have been invoked, the session contains information about the current user and his permissions, groups etc. - the Gateway then does authorization based upon the configured requirements. The input to this can come either directly from the configuration for the specific Location, or it can originate from an Authorization Plugin within the Session Controller - see Authorization Plugins for more info about these.

The gateway can perform authorization based upon role/group membership (Role Based Access Control or RBAC), permission / ACL (which supports attaching scripts to permissions, to do Attribute-Based Access Control or ABAC), it can check for specific OAuth2 scope, or it any custom script can be executed which can do basically whatever it wants to decide if authorization is allowed or not to this particular resource for this user.

Proxy Request to Destination

Once authorization has passed, request processing continues - usually with Proxying a request to a particular configured Destination Server (or a target server in a cluster of destination servers).

Other types of processing can also happen, such as the gateway serving static resources, sending a dynamic response, or invoking Pipelines and Tasks to do more advanced request processing than just proxying onwards.

When a Location proxies reuests to a destination, Ceptor Gateway selects one of the available Target Servers and prepares to forward the request to it.

The configuration for a destination or individual target server might contain additional limits - e.g. on number of concurrent requests, or it can contain so-called "Target Authentication Plugins" - these are responsible for providing authentication information to the target server - and they make it possible to authenticate the client using one method, but authenticate the client to the target server using a different method.... or they can simply forward information about the currently authenticated user to the target server.

More info on Target Authentication Plugins here: Destinations - Authentication and info on developing them here: Plugins

Once a target server has been selected, all the request headers and cookies are modified according to the rules defined in the processed Locations and Destinations, then a new request is constructed and forwarded to the target server along with an eventual HTTP request body.

When the response headers are read, they are modified according to the information saved from going though the locations earlier and sent back to the client. The response body (if present) is then streamed back to the client until the entire response is processed.

Once that is done, the final act for the gateway in handling this request is to write to the access log.

Gateway Tracing is your friend - try turning on trace and examining its output - it will show you in detail what happens with the processing of a single request, listing all the conditions being checked, the locations being processed and the authentication/authorization being done and the results thereof - this is a great tool for both gaining a better understanding of what happens, and for diagnosing eventual problems.

Inside the Session Controller

The Session Controller is invoked either when creating the session, or when authenticating the user.

Creating the session might also involve authenticating the user, in case the session is created from a token or ticket and not just created as an empty placeholder.

More details about the Session Controller can be found here: Ceptor Session Controller

When the Session Controller gets a request to authenticate the user, it gets invoked with essentially just 4 parameters; Session ID, Authentication Plugin Type ID, User ID and Credentials.

When the Session Controller starts up (or is reconfigured) it loads a list of authentication plugins, initializes them and keeps them ready for processing authentication requests.

There is no logical limit (except for the size of an integer ID and more practical limits such as memory) to the number of authentication plugins that can be loaded simultaneously - each plugin has its own unique Authentication Plugin Type ID, and the caller decides which plugin to invoke when calling the login() API in Ceptor Agent (or it might be determined by configuration in the agent).

You can view the list of loaded Authentication and Authorization plugins within a Session Controller using Ceptor Console by going to Server Status and selecting "Detailed Information" and "Authentication and authorization plugins"

When authenticating a user, the Session Controller finds the correct Authentication Plugin and session, and calls login() on it with the session, userid and credentials. It is then up to the authentication plugin to fill the session with information about the user based upon the credentials in the incoming call.

The Authentication Plugin within the Session Controller only has access to the session contents, userid and credentials and not the HTTP request or response - this is because the authentication plugin might be invoked by something other than the Gateway, perhaps something not even using the HTTP protocol at all.

Once the Authentication Plugin has authenticated the user, it returns and the session content is updated (and before returning the Session Controller ensures that all nodes in the cluster and all agents and gateways have cleared their eventual cache of old session contents).


© Ceptor ApS. All Rights Reserved.