Skip to content

Commit

Permalink
Encrypt primary keys
Browse files Browse the repository at this point in the history
Add release-notes and documentation.

340299, 373060
  • Loading branch information
fschinkel committed Apr 25, 2024
1 parent 0ddcdaa commit b610a73
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/modules/releasenotes/partials/release-notes-24.2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,9 @@ If you just want to play around with them without looking at the source code, yo
* https://scout.bsi-software.com/jswidgets/

// ----------------------------------------------------------------------------

[[iid-encryption]]
== IId encryption

This release introduces a mechanism to encrypt `IId` that are e.g. sent to the browser or provided by a REST endpoint.
For more information see xref:technical-guide:common-concepts/security.adoc#iid-encryption[IId encryption].
75 changes: 75 additions & 0 deletions docs/modules/technical-guide/pages/common-concepts/security.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,78 @@ The form based login also supports two-factor-authentication.

If the registered `ICredentialVerifier` requests a second factor by returning `AUTH_2FA_REQUIRED`, the `FormBasedAccessController` instructs the UI to show an input field so the user can enter the token.
To verify this token a second-factor verifier `ICredentialVerifier` needs to be registered.

[[iid-encryption]]
== IId encryption

Scout provides a mechanism to encrypt instances of `IId`. To use this feature simply pass the `IdCodecFlag.ENCRYPTION` to the `IdCodec` while serializing or deserializing the id.

.serialize an `IId` using encryption
[source,java]
----
BEANS.get(IdCodec.class).toQualified(id, IdCodecFlag.ENCRYPTION)
----

The default implementation will use the unqualified part of the serialized id and create a signature which is added as a suffix.
The validity of this signature is checked again when the id is deserialized.

.deserialize a `String` using encryption
[source,java]
----
BEANS.get(IdCodec.class).fromQualified(idString, IdCodecFlag.ENCRYPTION)
----

To use this feature one needs to set the config property `scout.idCrypterPassword` which is used to create the signature.

The signature can easily be extended by replacing the `IdCodec` and overriding the `createSignature` method. One can e.g. additionally use the current user id for the signature.
Also, the whole encryption can be changed by overriding `encryptUnqualified` and `decryptUnqualified`.

If an `IId` needs to be encrypted or not, depends on why it is serialized and the type of the id itself.
Does the `IId` need to be persisted into a database it is usually unencrypted as it can't be read again if the encryption changes.
But if the `IId` is sent to the browser or another application it typically needs to be encrypted. All data sent to the browser is serialized in the JSON layer and this serialization will always use encryption.
If an application provides e.g. REST endpoints two things need to be done to ensure encryption.

[#add-dependency]
1. A dependency to the `org.eclipse.scout.rt.rest.jersey.server` module needs to be added to the app module of the application.
[#add-header]
2. The header `X-ScoutIdEncryption` need to be added to all request.

The dependency added in xref:add-dependency[1.] will add the `IdEncryptionRestContainerFilter` which turns on the encryption for all requests containing the header `X-ScoutIdEncryption`.

.dependency to the `org.eclipse.scout.rt.rest.jersey.server` module
----
<dependency>
<groupId>org.eclipse.scout.rt</groupId>
<artifactId>org.eclipse.scout.rt.rest.jersey.server</artifactId>
</dependency>
----

The header in xref:add-header[2.] can be added in multiple ways. It can be added e.g. by a client like the browser directly or added by the server to all requests.
Let's say the application provides REST endpoints under `/api` the `IdEncryptionFilter` can be used to add the header to all requests to this path.

[source,java]
.Registration example for `IdEncryptionFilter`.
----
public static class ApiIdEncryptionFilterContributor implements IServletFilterContributor {
@Override
public void contribute(ServletContextHandler handler) {
handler.addFilter(IdEncryptionFilter.class, "/api/*", null);
}
}
----

If there is a special `IId` that does not support encryption it can be excluded from the encryption mechanism using the `IdEncryption` annotation.

[source,java]
.Exclude the `UnencryptedId` using the `IdEncryption` annotation.
----
@IdEncryption(false)
public final class UnencryptedId extends AbstractStringId {
private static final long serialVersionUID = 1L;
private UnencryptedId(String id) {
super(id);
}
}
----
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,9 @@ include::common:example$org.eclipse.scout.docs.snippets/src/main/java/org/eclips
----
include::common:example$org.eclipse.scout.docs.snippets/src/main/java/org/eclipse/scout/docs/snippets/rest/UploadResource.java[tags=method]
----

[[iid-encryption]]
== IId encryption

All instances of `IId` can be serialized and deserialized by the `IdCodec` using encryption. This can be used to encrypt ids that are read and written by a REST endpoint.
For more information see xref:technical-guide:common-concepts/security.adoc#iid-encryption[IId encryption].

0 comments on commit b610a73

Please sign in to comment.