AAD と AWS Cognito を使用してさまざまなエンドポイントの Spring Boot REST API を保護する

王林
リリース: 2024-02-22 13:22:06
転載
913 人が閲覧しました

php エディター Baicao は、AAD と AWS Cognito を使用して Spring Boot REST API を保護することに関する Java Q&A 記事を注意深く作成しました。この記事では、これら 2 つの認証サービスを活用してさまざまなエンドポイントを保護し、API の安全性を確保する方法を説明します。私たちのガイドに従って、Spring Boot プロジェクトに認証と認可を実装して、REST API をより強力で信頼性の高いものにする方法を学びましょう。

質問の内容

このトピックに関するリソースがどこにも見つからないため、誰かがここで私を助けてくれることを願っています。

Spring Boot Restapi があり、現在の構成には 2 つのルートがあります: 1. 非認証 2. aad/entra のベアラーを介して認証

私の構成方法は現在次のように設定されています:

リーリー

これは、aadresourceserverwebsecurityconfigureadapter を拡張するクラスでラップされています。

このように API を構成することで、次のようにルートを保護できます:

リーリー

新しいタイプのユーザーが認可エンドポイントを使用できるように API を拡張する必要があります。これらのユーザーは aws cognito によって管理されます。一部のパスを承認せず、一部のパスを aad 経由で保護し、一部のパスを aws cognito 経由で保護できるように websecurityconfigureadapter を設定するにはどうすればよいですか?

私が抱えている主な問題は、aadresourceserverwebsecurityconfigureadapter が Microsoft が提供するベアラーでのみ機能するように jwt 検証を構成していることです。

理想的には次のようなものが欲しいです:

リーリー

私が見つけたもう 1 つの問題は、aadresourceserverwebsecurityconfigureadapter が、jwtclaimnames の「roles」と「scp」のすべての可能なプレフィックスを「scope_」と「approle_」に自動的に設定することです。理想的には、aad と aws cognito で異なるものにして、「aad_scope_」、「aad_approle_」、「cognito_group_」という接頭辞を付けるようにしたいと思います。

スプリングブート用のマルチテナントjwt認証を実装する方法を説明する情報をいくつか見つけましたが、それらはすべてSQLデータベースを使用してパスワード/ユーザーベースの認証を実装するだけです。

aws cognito によって提供される jwt の検証を組み込むことができるように、基本的にすべての aad ロジックを再実装する必要がある方法はありますか、それともルーティングに基づいて決定を行う方法はありますか?

httpsecurityoauth2resourceserver() 関数を使用して jwt の使用を構成できることはすでに知っていますが、その機能を単一のテナントに実装する方法に関する情報しか見つかりませんでした。

この特定のケースまたは同様のケースをうまく実装した人、または私を正しい方向に導いてくれる人がいたら、非常に感謝します。 あるいは、私の考えが完全に間違っているかもしれないので、教えてください。

実用的なソリューションの更新の使用 (2024 年 1 月 25 日)

@ch4mp の回答のおかげで、成功しました。 >実用的な回答<

私の実装は非常に単純化され、次のようになります:

アプリケーション.yml

リーリー

セキュリティ構成

リーリー

私のコントローラーは次のようになります:

リーリー

Build.gradle

リーリー

これ Springの公式ランチャーではなく、OSS実装です: https://www.php.cn/link/49844ba129a1cbc3d964703fcdb756ba

他の問題が発生した場合は再度更新しますが、今のところは問題なく動作しています。

解決策

簡単なので、私のスターターを使用してここで解決策を公開します。

「公式」スプリング ブート ランチャーのみを使用して安全な構成を構築したい場合は、認証マネージャーごとに、iss 宣言を使用して独自の authenticationmanagerresolver<httpserletrequest> を提供する必要があります。各サーバーには、必要なオリジン クレームとプレフィックスを処理するための独自の認証コンバーターと独自のアクセス許可コンバーターがあります。例と実装のヒントについては、<a href="https://www.php.cn/link/49844ba129a1cbc3d964703fcdb756ba/tree/master/samples/tutorials" rel="nofollow noreferrer">私のチュートリアル</a> または <a href="https://www.php.cn/link/37841383bc8c327de7912cf44790f3fd" rel="nofollow noreferrer">公式ドキュメント</a>を参照してください。 <a href="https://www.php.cn/link/945a1b4276b1524763d2acc19dc8c475">この他の回答</a>も役立つかもしれません(権限マッピングの要件は完全に異なりますが、認証マネージャーのリゾルバーは似ています)。 </p> <h3>ブート <code>3.2.2 と spring-addons を使用します リーリー リーリー

次の application.yaml を編集して、独自のパブリッシャーを配置します:

リーリー

上記の path の値は json パスです。 jsonpath.com などのツールを使用して、独自のトークン ペイロード (jwt.io などのツールを使用して抽出された) に対してパス式をテストできます。

はい、とても簡単です。いいえ、yaml プロパティや Java 設定を省略したわけではありません (信じられない場合は、新しいプロジェクトでテストしてください)。

示例控制器

@restcontroller
public class greetcontroller {

    @getmapping("/greet")
    @preauthorize("isauthenticated()")
    public string getgreet(authentication auth) {
        return "hello %s! you are granted with %s.".formatted(auth.getname(), auth.getauthorities());
    }

    @getmapping(value = "/strings")
    @preauthorize("hasanyauthority('aad_approle_admin', 'cognito_group_admin')")
    public list<string> getstrings() {
        return list.of("protected", "strings");
    }
}
ログイン後にコピー

示例测试

@webmvctest(controllers = greetcontroller.class)
@autoconfigureaddonswebmvcresourceserversecurity
@import(securityconf.class)
class greetcontrollertest {
    @autowired
    mockmvcsupport api;

    @test
    @withanonymoususer
    void givenuserisanonymous_whengetgreet_thenunauthorized() throws unsupportedencodingexception, exception {
        api.get("/greet").andexpect(status().isunauthorized());
    }

    @test
    @withjwt("aad_admin.json")
    void givenuserisaadadmin_whengetgreet_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/greet").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals(
            "hello aad-admin! you are granted with [aad_approle_msiam_access, aad_approle_admin, aad_scope_openid, aad_scope_profile, aad_scope_machin:truc].",
            actual);
    }

    @test
    @withjwt("cognito_admin.json")
    void givenuseriscognitoadmin_whengetgreet_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/greet").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals("hello amazon-cognito-admin! you are granted with [cognito_group_admin, cognito_group_machin:truc].", actual);
    }

    @test
    @withjwt("aad_machin-truc.json")
    void givenuserisaadmachintruc_whengetgreet_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/greet").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals("hello aad-user! you are granted with [aad_approle_msiam_access, aad_scope_openid, aad_scope_profile, aad_scope_machin:truc].", actual);
    }

    @test
    @withjwt("cognito_machin-truc.json")
    void givenuseriscognitomachintruc_whengetgreet_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/greet").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals("hello amazon-cognito-user! you are granted with [cognito_group_machin:truc].", actual);
    }

    @test
    @withanonymoususer
    void givenuserisanonymous_whengetstrings_thenunauthorized() throws unsupportedencodingexception, exception {
        api.get("/strings").andexpect(status().isunauthorized());
    }

    @test
    @withjwt("aad_admin.json")
    void givenuserisaadadmin_whengetstrings_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/strings").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals("[\"protected\",\"strings\"]", actual);
    }

    @test
    @withjwt("cognito_admin.json")
    void givenuseriscognitoadmin_whengetstrings_thenok() throws unsupportedencodingexception, exception {
        final var actual = api.get("/strings").andexpect(status().isok()).andreturn().getresponse().getcontentasstring();
        assertequals("[\"protected\",\"strings\"]", actual);
    }

    @test
    @withjwt("aad_machin-truc.json")
    void givenuserisaadmachintruc_whengetstrings_thenforbidden() throws unsupportedencodingexception, exception {
        api.get("/strings").andexpect(status().isforbidden());
    }

    @test
    @withjwt("cognito_machin-truc.json")
    void givenuseriscognitomachintruc_whengetstrings_thenforbidden() throws unsupportedencodingexception, exception {
        api.get("/strings").andexpect(status().isforbidden());
    }

}
ログイン後にコピー

使用此测试资源:

  • aad_admin.json
{
    "sub": "aad-admin",
    "iss": "https://sts.windows.net/0a962d63-6b23-4416-81a6-29f88c553998/",
    "approles": [
        {
          "allowedmembertypes": [
            "user"
          ],
          "description": "msiam_access",
          "displayname": "msiam_access",
          "id": "ef7437e6-4f94-4a0a-a110-a439eb2aa8f7",
          "isenabled": true,
          "origin": "application",
          "value": null
        },
        {
          "allowedmembertypes": [
            "user"
          ],
          "description": "administrators only",
          "displayname": "admin",
          "id": "4f8f8640-f081-492d-97a0-caf24e9bc134",
          "isenabled": true,
          "origin": "serviceprincipal",
          "value": "administrator"
        }
    ],
    "scope": "openid profile machin:truc"
}
ログイン後にコピー
  • aad_machin-truc.json
{
    "sub": "aad-user",
    "iss": "https://sts.windows.net/0a962d63-6b23-4416-81a6-29f88c553998/",
    "approles": [
        {
          "allowedmembertypes": [
            "user"
          ],
          "description": "msiam_access",
          "displayname": "msiam_access",
          "id": "ef7437e6-4f94-4a0a-a110-a439eb2aa8f7",
          "isenabled": true,
          "origin": "application",
          "value": null
        }
    ],
    "scope": "openid profile machin:truc"
}
ログイン後にコピー
  • cognito_admin.json
{
    "sub": "amazon-cognito-admin",
    "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_rzhmglwjl",
    "cognito:groups": ["admin", "machin:truc"],
    "scope": "openid profile cog:scope"
}
ログイン後にコピー
  • cognito_machin-truc.json
{
    "sub": "amazon-cognito-user",
    "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_RzhmgLwjl",
    "cognito:groups": ["machin:truc"],
    "scope": "openid profile cog:scope"
}
ログイン後にコピー

以上がAAD と AWS Cognito を使用してさまざまなエンドポイントの Spring Boot REST API を保護するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:stackoverflow.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!