Inverno Framework Security

Jeremy Kuhn
ITNEXT
Published in
5 min readAug 16, 2022

--

Following the latest publication of the Web Framework Benchmarks by TechEmpower which confirm its very good performance, the latest release of the Inverno Framework comes with an extensible security API and a set of modules which allow to secure any kind of application from standalone to microservices applications.

Application security is a complex subject that involves many concerns such as authentication, identification, authorization, cryptography… as well as multiple techniques to protect against more and more sophisticated attacks. Over the year many security related specifications were published to address these points and it gets easy to get lost when securing an application.

The Inverno Framework security API has been designed around a well identified security model in order to simplify this task.

This article is meant to give you and overview on how security is implemented in an Inverno application and present some common features, please refer to the Inverno Framework reference documentation if you need to go deeper.

Security Model

The Inverno security model is based on three main concepts:

  • Authentication which covers the authentication of a request made to an application. It basically consists in authenticating any kind of credentials (e.g. username/password, token…) provided in a request (and not the actual entity behind the request).
  • Identification which covers the identification of the entity behind an authenticated request. We might not always have identification either because it is not needed by the application or because the authentication mechanism does not allow to get identity information (e.g. OAuth2).
  • Access control which covers the control of access to protected services or resources in the application for an authenticated entity based on roles, permissions… As for identification, access control depends on both the application and the authentication mechanism and it might not always be available.

These three concepts are the basis of the security API and are practically all you need to know to properly secure access to an application.

Security Manager

The security manager, or the security interceptor for a Web application, is the main security component responsible for authenticating credentials and creating a resulting security context with identity information and an access controller that can then be used to protect access to services and resources through the application.

The following shows how to create a security manager capable of authenticating login credentials (username/password), resolving the actual identity of the authenticated entity and a Role-based access controller:

In above code, the user authenticator uses a user repository to resolve trusted credentials and a login credentials matcher to match them with the provided login credentials. The user repository is a secured repository where users credentials are stored in-memory or in an external data store (e.g. Redis). From there, an identity resolver and/or an access controller resolver can be specified when identity information and/or access controller are required by the application.

As you can see, this approach is quite flexible and allows to authenticate different kind of credentials, resolve different kind of identities and access controllers depending on the application. For instance, the authenticator can be changed or composed to authenticate other kind of credentials or extended login credentials in order to implement two factor authentication, leaving identity and access control resolvers untouched.

Security Context

The security manager can then be used to authenticate credentials and obtain a corresponding security context:

In above code, login credentials to authenticate are created using a username and a raw password but an encoded password could have been specified as well. The security manager is then invoked to authenticate the credentials and obtain a security context, as always the security manager is fully reactive.

The resulting security context can then be either denied on failed authentication, anonymous when null credentials were specified or authenticated on successful authentication. This allows to let the application decide what to do in the different use cases. For instance the following code shows a proper way to handle a security context:

Identity

The security context may expose the identity of the authenticated entity if the security manager was able to resolve it. The identity shall be used whenever identity information are required, to get an email address for instance or any other useful information about the authenticated entity: age, office location, URLs…

The actual identity type is determined by the security manager and can depend on the application and the authentication mechanism. For instance, an LDAP directory, a simple user repository or an Open ID token provide different information about the authenticated entity.

Access Control

The security context may also expose an access controller to control the access to protected services or resources for the authenticated entity based on its roles, permissions or any other access control mechanism.

Above security manager has been configured to resolve Role-based access controller from the groups of the authenticated user. This is possible since users in a user repository can be placed in groups, just like users in an LDAP directory. As you can see, as for the identity, the kind of access controller depends on the application and what information are available to resolve it.

A Role-based access controller is used to determine whether the authenticated user has a specific role, any or all of the roles in a set of roles:

In above code, we try to determine whether the authenticated entity has role admin which is always false when no access controller is available.

The security module also provides permission based access control which supports parameterized permissions and allows a precise control of access by taking the functional context into account. For instance it is possible to determine whether a permission has been granted to access a particular type of resources.

In above code, a permission-based access controller is used to determine whether the authenticated entity has permission create on article documents. Note that an exception is thrown if the access controller is missing.

Summary

The concepts described in this article are the basis to Inverno application security which is always based on authentication, identification and access control composed in a security manager in order to authenticate credentials and produce the application security context actually used to protect services and resources.

The security modules provide various implementations and more specific features to help you secure standalone applications as well as Web applications. The list of available features is pretty complete and allows to properly implement security in an application, it includes:

  • Authentication and identification against a user repository (in-memory, Redis)
  • Token based authentication
  • Secured password encoding using message digest, Argon2, PBKDF2, BCrypt, SCrypt
  • Role-based access control
  • Permission-based access control
  • JSON Object Signing and Encryption support (RFC7515, RFC7516, RFC7517, RFC7518, RFC7519, RFC7638, RFC7797, RFC8037, RFC8812)
  • Authentication and identification against LDAP and Active Directory
  • HTTP basic (RFC7617) and digest (RFC7616) authentication
  • Form-based authentication
  • Cross-origin resource sharing support (CORS)
  • Protection against Cross-site request forgery attack (CSRF)

A complete documentation and several user guides are also available to help you in the process of securing an Inverno application.

--

--