検索

8.5. アプリケーションの作成

download PDF

まず、ProtectedResource を実装します。

package org.acme.security.openid.connect.client;

import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;

import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Uni;

import org.eclipse.microprofile.jwt.JsonWebToken;

@Path("/protected")
@Authenticated
public class ProtectedResource {

    @Inject
    JsonWebToken principal;

    @GET
    @RolesAllowed("user")
    @Produces("text/plain")
    @Path("userName")
    public Uni<String> userName() {
        return Uni.createFrom().item(principal.getName());
    }

    @GET
    @RolesAllowed("admin")
    @Produces("text/plain")
    @Path("adminName")
    public Uni<String> adminName() {
        return Uni.createFrom().item(principal.getName());
    }
}

ProtectedResource は、userName() メソッドと adminName() メソッドの両方から名前を返します。名前は現在の JsonWebToken から展開されます。

次に、FrontendResourceProtectedResource を呼び出すために使用する 2 つの REST クライアント OidcClientRequestReactiveFilter および AccessTokenRequestReactiveFilter を追加します。

OidcClientRequestReactiveFilter REST クライアントを追加します。

package org.acme.security.openid.connect.client;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;

import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import io.quarkus.oidc.client.reactive.filter.OidcClientRequestReactiveFilter;
import io.smallrye.mutiny.Uni;

@RegisterRestClient
@RegisterProvider(OidcClientRequestReactiveFilter.class)
@Path("/")
public interface RestClientWithOidcClientFilter {

    @GET
    @Produces("text/plain")
    @Path("userName")
    Uni<String> getUserName();

    @GET
    @Produces("text/plain")
    @Path("adminName")
    Uni<String> getAdminName();
}

RestClientWithOidcClientFilter インターフェイスは、トークンを取得して伝播するために OidcClientRequestReactiveFilter に依存します。

AccessTokenRequestReactiveFilter REST クライアントを追加します。

package org.acme.security.openid.connect.client;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;

import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import io.quarkus.oidc.token.propagation.reactive.AccessTokenRequestReactiveFilter;
import io.smallrye.mutiny.Uni;

@RegisterRestClient
@RegisterProvider(AccessTokenRequestReactiveFilter.class)
@Path("/")
public interface RestClientWithTokenPropagationFilter {

    @GET
    @Produces("text/plain")
    @Path("userName")
    Uni<String> getUserName();

    @GET
    @Produces("text/plain")
    @Path("adminName")
    Uni<String> getAdminName();
}

RestClientWithTokenPropagationFilter インターフェイスは、受信する既存のトークンを伝播するために AccessTokenRequestReactiveFilter に依存します。

RestClientWithOidcClientFilter インターフェイスと RestClientWithTokenPropagationFilter インターフェイスは、どちらも同じであることに注意してください。これは、同じ REST Client 上で OidcClientRequestReactiveFilter および AccessTokenRequestReactiveFilter を組み合わせると、両方のフィルターが相互に干渉する可能性があるため、副作用が発生するためです。たとえば、OidcClientRequestReactiveFilter は、AccessTokenRequestReactiveFilter によって伝播されたトークンをオーバーライドできます。また、伝播できるトークンがなく、代わりに OidcClientRequestReactiveFilter が新しいトークンを取得することが予想されるときにそれが呼び出されると、AccessTokenRequestReactiveFilter が失敗する可能性があります。

次に、FrontendResource を追加してアプリケーションの作成を完了します。

package org.acme.security.openid.connect.client;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;

import org.eclipse.microprofile.rest.client.inject.RestClient;

import io.smallrye.mutiny.Uni;

@Path("/frontend")
public class FrontendResource {
    @Inject
    @RestClient
    RestClientWithOidcClientFilter restClientWithOidcClientFilter;

    @Inject
    @RestClient
    RestClientWithTokenPropagationFilter restClientWithTokenPropagationFilter;

    @GET
    @Path("user-name-with-oidc-client-token")
    @Produces("text/plain")
    public Uni<String> getUserNameWithOidcClientToken() {
        return restClientWithOidcClientFilter.getUserName();
    }

    @GET
    @Path("admin-name-with-oidc-client-token")
    @Produces("text/plain")
    public Uni<String> getAdminNameWithOidcClientToken() {
	    return restClientWithOidcClientFilter.getAdminName();
    }

    @GET
    @Path("user-name-with-propagated-token")
    @Produces("text/plain")
    public Uni<String> getUserNameWithPropagatedToken() {
        return restClientWithTokenPropagationFilter.getUserName();
    }

    @GET
    @Path("admin-name-with-propagated-token")
    @Produces("text/plain")
    public Uni<String> getAdminNameWithPropagatedToken() {
        return restClientWithTokenPropagationFilter.getAdminName();
    }
}

FrontendResource は、/frontend/user-name-with-oidc-client-token または /frontend/admin-name-with-oidc-client-token のいずれかが呼び出されたときに、OIDC トークン伝播 Reactive フィルターを備えた REST クライアントを使用して、ProtectedResource へのアクセストークンを取得して伝播します。また、FrontendResource は、/frontend/user-name-with-propagated-token または /frontend/admin-name-with-propagated-token のいずれかが呼び出されたときに OpenID Connect Token Propagation Reactive Filter を備えた REST Client を使用して、現在の受信アクセストークンを ProtectedResource に伝播します。

最後に、Jakarta REST ExceptionMapper を追加します。

package org.acme.security.openid.connect.client;

import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;

import org.jboss.resteasy.reactive.ClientWebApplicationException;

@Provider
public class FrontendExceptionMapper implements ExceptionMapper<ClientWebApplicationException> {

	@Override
	public Response toResponse(ClientWebApplicationException t) {
		return Response.status(t.getResponse().getStatus()).build();
	}

}

この例外マッパーは、トークンに予期されるロールがない場合に ProtectedResource403 を返すことをテスト中に検証するためにのみ追加されます。このマッパーがなければ、RESTEasy Reactive は、REST クライアント呼び出しから逃れた例外を 500 に正しく変換し、ProtectedResource などのダウンストリームリソースからの情報の漏洩を回避します。ただし、テストでは、500 が何らかの内部エラーではなく、認可例外によって発生したと断言することはできません。

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.