The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Built-In Authentication Support

The following section describes the Quarkus built-in authentication mechanisms for HTTP based FORM, BASIC, and Mutual TLS authentication. Proactive authentication is also described.

ベーシック認証

HTTP Basic Authentication uses fields in the HTTP header and is the easiest to set up. Also, it is one of the least resource-demanding techniques that enforce access controls to the Web resources without requiring HTTP cookies, session identifiers, or login pages.

In the context of an HTTP request, Basic authentication is a method for an HTTP user agent, such as a web browser, to provide a user name and password when creating a request. In Basic HTTP Authentication, a request contains a header field in the form of Authorization: Basic <credentials>, where credentials are the Base64 encoding of a user ID and password joined by a colon as described in the following example.

If the user name is Alice and the password is secret, the HTTP authorization header looks authorization as Authorization: Basic QWxjZTpzZWNyZXQ=, where QWxjZTpzZWNyZXQ= is a Base64 encoded representation of the Alice:secret string.

The Basic Authentication mechanism does not provide confidentiality protection for the transmitted credentials. The credentials are merely encoded with Base64 when in transit and not encrypted or hashed in any way. Therefore, Basic Authentication is used with HTTPS to provide confidentiality.

Enabling Basic Authentication

前提条件
  • You have installed at least one extension that provides an IdentityProvider based on username and password, such as Elytron JDBC.

Procedure
  • Enable Basic Authentication by setting the value of quarkus.http.auth.basic property to true.

    quarkus.http.auth.basic=true

For a Basic Authentication configuration walk-through that uses JPA, see the Getting Started With Security guide.

フォームベース認証

Quarkus provides form based authentication that works in a similar manner to traditional Servlet form based auth. Unlike traditional form authentication, the authenticated user is not stored in an HTTP session, as Quarkus does not provide clustered HTTP session support. Instead, the authentication information is stored in an encrypted cookie, which can be read by all members of the cluster (provided they all share the same encryption key).

暗号化キーは quarkus.http.auth.session.encryption-key プロパティーを使って設定でき、少なくとも 16 文字の長さでなければなりません。このキーは SHA-256 を使ってハッシュ化され、その結果のダイジェストがクッキー値の AES-256 暗号化のキーとして使用されます。このクッキーは暗号化された値の一部として有効期限を含んでいますので、クラスター内のすべての ノードはクロックを同期させなければなりません。1 分間隔で、セッションが使用中であれば、更新された有効期限時間を持つ新しいクッキーが生成されます。

以下のプロパティーを使用して、フォームベース認証を設定することができます。

ビルド時に固定される設定プロパティ - それ以外の設定プロパティは実行時に上書き可能

Configuration property

タイプ

デフォルト

If form authentication is enabled

Environment variable: QUARKUS_HTTP_AUTH_FORM_ENABLED

boolean

false

The login page

Environment variable: QUARKUS_HTTP_AUTH_FORM_LOGIN_PAGE

string

/login.html

The post location.

Environment variable: QUARKUS_HTTP_AUTH_FORM_POST_LOCATION

string

/j_security_check

The username field name.

Environment variable: QUARKUS_HTTP_AUTH_FORM_USERNAME_PARAMETER

string

j_username

The password field name.

Environment variable: QUARKUS_HTTP_AUTH_FORM_PASSWORD_PARAMETER

string

j_password

The error page

Environment variable: QUARKUS_HTTP_AUTH_FORM_ERROR_PAGE

string

/error.html

The landing page to redirect to if there is no saved page to redirect back to

Environment variable: QUARKUS_HTTP_AUTH_FORM_LANDING_PAGE

string

/index.html

Option to disable redirect to landingPage if there is no saved page to redirect back to. Form Auth POST is followed by redirect to landingPage by default.

Environment variable: QUARKUS_HTTP_AUTH_FORM_REDIRECT_AFTER_LOGIN

boolean

true

Option to control the name of the cookie used to redirect the user back to where he wants to get access to.

Environment variable: QUARKUS_HTTP_AUTH_FORM_LOCATION_COOKIE

string

quarkus-redirect-location

The inactivity (idle) timeout When inactivity timeout is reached, cookie is not renewed and a new login is enforced.

Environment variable: QUARKUS_HTTP_AUTH_FORM_TIMEOUT

Duration

PT30M

How old a cookie can get before it will be replaced with a new cookie with an updated timeout, also referred to as "renewal-timeout". Note that smaller values will result in slightly more server load (as new encrypted cookies will be generated more often), however larger values affect the inactivity timeout as the timeout is set when a cookie is generated. For example if this is set to 10 minutes, and the inactivity timeout is 30m, if a users last request is when the cookie is 9m old then the actual timeout will happen 21m after the last request, as the timeout is only refreshed when a new cookie is generated. In other words no timeout is tracked on the server side; the timestamp is encoded and encrypted in the cookie itself, and it is decrypted and parsed with each request.

Environment variable: QUARKUS_HTTP_AUTH_FORM_NEW_COOKIE_INTERVAL

Duration

PT1M

The cookie that is used to store the persistent session

Environment variable: QUARKUS_HTTP_AUTH_FORM_COOKIE_NAME

string

quarkus-credential

期間フォーマットについて

期間のフォーマットは標準の java.time.Duration フォーマットを使用します。詳細は Duration#parse() javadoc を参照してください。

数値で始まる期間の値を指定することもできます。この場合、値が数値のみで構成されている場合、コンバーターは値を秒として扱います。そうでない場合は、 PT が暗黙的に値の前に付加され、標準の java.time.Duration 形式が得られます。

相互TLS認証

QuarkusはmTLS認証を提供しているので、X.509証明書に基づいてユーザーを認証できます。

To use this authentication method, you should first enable SSL for your application. For more details, check the Supporting secure connections with SSL guide.

アプリケーションが安全な接続を受け入れたら、次のステップは、アプリケーションが信頼すべきすべての証明書を保持する quarkus.http.ssl.certificate.trust-store-file を設定し、クライアント(例: ブラウザや他のサービス)が保護されたリソースにアクセスしようとしたときに、アプリケーションがどのように証明書を要求するかを設定します。

quarkus.http.ssl.certificate.key-store-file=server-keystore.jks            (1)
quarkus.http.ssl.certificate.key-store-password=the_key_store_secret
quarkus.http.ssl.certificate.trust-store-file=server-truststore.jks        (2)
quarkus.http.ssl.certificate.trust-store-password=the_trust_store_secret
quarkus.http.ssl.client-auth=required                                      (3)

quarkus.http.auth.permission.default.paths=/*                              (4)
quarkus.http.auth.permission.default.policy=authenticated
1 サーバーの秘密鍵が置かれている鍵ストアを設定します。
2 信頼された証明書がロードされるトラストストアを構成します。
3 サーバーが *常に*クライアントからの証明書を要求することを定義します。 REQUEST を使用することで、この動作を緩和することができます。mTLS 以外の認証方法もサポートしている場合に便利です。
4 認証されたユーザーのみがアプリケーションからリソースにアクセスできるようにするポリシーを定義します。

受信したリクエストがトラストストアの有効な証明書と一致したら、アプリケーションは以下のように SecurityIdentity を注入するだけでサブジェクトを取得できるようになるはずです。

subjectの取得
@Inject
SecurityIdentity identity;

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
    return String.format("Hello, %s", identity.getPrincipal().getName());
}

また、以下のように証明書を取得できるようにしておきましょう:

証明書の取得
import java.security.cert.X509Certificate;
import io.quarkus.security.credential.CertificateCredential;

CertificateCredential credential = identity.getCredential(CertificateCredential.class);
X509Certificate certificate = credential.getCertificate();

認可

The information from the client certificate can be used to enhance Quarkus SecurityIdentity. For example, one can add new roles after checking a client certificate subject name, and so on. Please see the SecurityIdentity Customization section for more information about customizing Quarkus SecurityIdentity.

プロアクティブ認証

By default, Quarkus does what we call proactive authentication. This means that if an incoming request has a credential then that request will always be authenticated (even if the target page does not require authentication).

これは、公開ページであっても、無効なクレデンシャルを持つリクエストは常に拒否されることを意味します。この動作を変更して、 quarkus.http.auth.proactive=false を設定することで必要な場合のみ認証を行うことができます。

If you disable proactive authentication then the authentication process will only be run when an identity is requested, either because there are security rules that requires the user to be authenticated, or due to programmatic access to the current identity.

Note that if proactive authentication is in use accessing the SecurityIdentity is a blocking operation. This is because authentication may not have happened yet, and accessing it may require calls to external systems such as databases that may block. For blocking applications this is no problem, however if you have disabled authentication in a reactive application this will fail (as you cannot do blocking operations on the IO thread). To work around this you need to @Inject an instance of io.quarkus.security.identity.CurrentIdentityAssociation, and call the Uni<SecurityIdentity> getDeferredIdentity(); method. You can then subscribe to the resulting Uni and will be notified when authentication is complete and the identity is available.

It’s still possible to access the SecurityIdentity synchronously with public SecurityIdentity getIdentity() in the RESTEasy Reactive from endpoints annotated with @RolesAllowed, @Authenticated, or with respective configuration authorization checks as authentication has already happened. The same is also valid for the Reactive routes if a route response is synchronous.

How to customize authentication exception responses

By default, the authentication security constraints are enforced before the JAX-RS chain starts. Disabling the proactive authentication effectively shifts this process to the moment when the JAX-RS chain starts running thus making it possible to use JAX-RS ExceptionMapper to capture Quarkus Security authentication exceptions such as io.quarkus.security.AuthenticationFailedException, for example:

package io.quarkus.it.keycloak;

import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import io.quarkus.security.AuthenticationFailedException;

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFailedExceptionMapper implements ExceptionMapper<AuthenticationFailedException> {

    @Context
    UriInfo uriInfo;

    @Override
    public Response toResponse(AuthenticationFailedException exception) {
        return Response.status(401).header("WWW-Authenticate", "Basic realm=\"Quarkus\"").build();
    }
}