1.6. ステップアップ認証
io.quarkus.oidc.AuthenticationContext アノテーションを使用すると、1 つ以上の Authentication Context Class Reference (ACR) 値をリストして、Jakarta REST リソースクラスとメソッドに必要な認証レベルを適用できます。OAuth 2.0 Step Up Authentication Challenge Protocol は、トークンに期待される Authentication Context Class Reference (ACR) 値がない場合に、リソースサーバーがより強力な認証方法を要求できるメカニズムを導入します。以下の例を考慮してください。
package io.quarkus.it.oidc;
import io.quarkus.oidc.AuthenticationContext;
import io.quarkus.oidc.BearerTokenAuthentication;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@BearerTokenAuthentication
@Path("/")
public class GreetingsResource {
@Path("hello")
@AuthenticationContext("myACR")
@GET
public String hello() {
return "hello";
}
@Path("hi")
@AuthenticationContext(value = "myACR", maxAge = "PT120m")
@GET
public String hi() {
return "hi";
}
}
quarkus.http.auth.proactive=false
- 1
- プロアクティブ認証を無効にして、Quarkus が受信リクエストを認証する前に、
@AuthenticationContextアノテーションをエンドポイントと一致できるようにします。
ベアラーアクセストークンクレーム acr に myACR が含まれていない場合、Quarkus は必要な acr_values を示す認証要件チャレンジを返します。
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="insufficient_user_authentication",
error_description="A different authentication level is required",
acr_values="myACR"
シングルページアプリケーション (SPA) などのクライアントが insufficient_user_authentication エラーコードを含むチャレンジを受信すると、acr_values を解析して、acr_values 制約を満たす新しいユーザーログインを要求し、新しいアクセストークンを使用して Quarkus にアクセスする必要があります。
io.quarkus.oidc.AuthenticationContext アノテーションは、WebSockets Next サーバーエンドポイントに必要な認証レベルを強制するためにも使用できます。HTTP 接続が WebSocket 接続にアップグレードされる前に SecurityIdentity が作成されるため、アノテーションをエンドポイントクラスに配置する必要があります。HTTP アップグレードのセキュリティーの詳細は、Quarkus の 「WebSockets Next リファレンス」ガイドの Secure HTTP upgrade セクションを参照してください。
OIDC テナントに必要な認証レベルを強制することもできます。
quarkus.oidc.hr.token.required-claims.acr=myACR
または、より柔軟性が必要な場合は、Jose4j Validator を作成します。
package io.quarkus.it.oidc;
import java.util.Map;
import jakarta.enterprise.context.ApplicationScoped;
import org.jose4j.jwt.MalformedClaimException;
import org.jose4j.jwt.consumer.JwtContext;
import org.jose4j.jwt.consumer.Validator;
import io.quarkus.arc.Unremovable;
import io.quarkus.oidc.TenantFeature;
import io.quarkus.oidc.common.runtime.OidcConstants;
import io.quarkus.security.AuthenticationFailedException;
@Unremovable
@ApplicationScoped
@TenantFeature("hr")
public class AcrValueValidator implements Validator {
@Override
public String validate(JwtContext jwtContext) throws MalformedClaimException {
var jwtClaims = jwtContext.getJwtClaims();
if (jwtClaims.hasClaim("acr")) {
var acrClaim = jwtClaims.getStringListClaimValue("acr");
if (acrClaim.contains("myACR") && acrClaim.contains("yourACR")) {
return null;
}
}
String requiredAcrValues = "myACR,yourACR";
throw new AuthenticationFailedException(Map.of(OidcConstants.ACR_VALUES, requiredAcrValues));
}
}