cari
RumahJavaMengamankan Spring Boot REST API untuk titik akhir yang berbeza menggunakan AAD dan AWS Cognito

editor php Baicao telah menulis artikel Soal Jawab Java dengan teliti untuk anda tentang menggunakan AAD dan AWS Cognito untuk melindungi Spring Boot REST API. Dalam artikel ini, kami akan meneroka cara memanfaatkan kedua-dua perkhidmatan pengesahan ini untuk melindungi titik akhir yang berbeza dan memastikan API anda selamat dan terjamin. Ikuti panduan kami dan ketahui cara melaksanakan pengesahan dan kebenaran dalam projek Spring Boot anda untuk menjadikan API REST anda lebih berkuasa dan boleh dipercayai.

Kandungan soalan

Semoga seseorang dapat membantu saya di sini kerana saya tidak dapat mencari sebarang sumber mengenai topik ini di mana-mana sahaja.

Saya mempunyai restapi but spring, dan konfigurasi semasa mempunyai dua laluan: 1. Tidak dibenarkan 2. Diizinkan melalui pembawa aad/entra

Kaedah konfigurasi saya pada masa ini disediakan seperti berikut:

@override
protected void configure(httpsecurity http) throws exception {
        super.configure(http);
        http.csrf().disable();
        http.authorizerequests(requests -> requests
                .antmatchers(httpmethod.options, "/**/**").permitall()
                .antmatchers("/api/protected/**").fullyauthenticated()
                .anyrequest().permitall()
        );
}

Ia dibungkus dalam kelas yang memanjang aadresourceserverwebsecurityconfigureradapter.

Dengan mengkonfigurasi api kami dengan cara ini, kami dapat menjamin laluan kami seperti berikut:

@preauthorize("hasauthority('approle_appname.rolename')")
@getmapping(value = "/some-method", produces = mediatype.application_json_value)
public responseentity<list<string>> getstrings() {
    return responseentity.ok(...);
}

Api kami kini perlu dilanjutkan untuk membolehkan jenis pengguna baharu menggunakan titik akhir kebenaran. Pengguna ini diuruskan oleh aws cognito. Bagaimanakah cara saya menyediakan websecurityconfigureradapter saya untuk membenarkan beberapa laluan tidak dibenarkan, beberapa laluan dilindungi melalui aad dan beberapa laluan untuk dilindungi melalui aws cognito?

Masalah utama yang saya nampak ialah aadresourceserverwebsecurityconfigureradapter mengkonfigurasi pengesahan jwt sedemikian rupa sehingga ia hanya berfungsi dengan pembawa yang disediakan oleh microsoft.

Sebaik-baiknya saya ingin sesuatu seperti ini:

@configuration
@enablewebsecurity
@enableglobalmethodsecurity(prepostenabled = true)
public class securityconfig extends websecurityconfigureradapter { 

    @configuration
    @order(1)
    public static class azureadsecurityconfig extends aadresourceserverwebsecurityconfigureradapter {

        @override
        protected void configure(httpsecurity http) throws exception {
            http.authorizerequests(requests -> requests
                    .antmatchers("/api/aad/**").fullyauthenticated()
            );
            http.oauth2resourceserver().jwt([utilize aad jwt validation]);
        }

    }

    @configuration
    @order(2)
    public static class awscognitosecurityconfig extends websecurityconfigureradapter {

        @override
        protected void configure(httpsecurity http) throws exception {
            http.authorizerequests(requests -> requests
                    .antmatchers("/api/cognito/**").fullyauthenticated()
            );
            http.oauth2resourceserver().jwt([utilize aws cognito jwt validation]);
        }
    }

    @configuration
    @order(3)
    public static class defaultsecurityconfig extends websecurityconfigureradapter {

            @override
            protected void configure(httpsecurity http) throws exception {
                http.csrf().disable();
                http.authorizerequests(requests -> requests
                        .antmatchers(httpmethod.options, "/**/**").permitall()
                        .anyrequest().permitall()
                );
            }
    }

}

Satu lagi isu yang saya temui ialah aadresourceserverwebsecurityconfigureradapter secara automatik menetapkan semua kemungkinan awalan untuk jwtclaimnames "peranan" dan "scp" kepada "skop_" dan "approle_". Sebaik-baiknya saya ingin mereka berbeza untuk aad dan aws kognito supaya saya awalan "aad_scope_", "aad_approle_" dan "cognito_group_".

Saya menemui beberapa maklumat yang menerangkan cara melaksanakan pengesahan jwt berbilang penyewa untuk but spring, tetapi mereka semua hanya menggunakan pangkalan data sql untuk melaksanakan pengesahan berasaskan kata laluan/pengguna.

Adakah terdapat cara di mana saya pada asasnya perlu melaksanakan semula semua logik iklan supaya saya boleh mencampurkan pengesahan jwt yang diberikan oleh aws cognito, atau adakah terdapat cara untuk membuat keputusan berdasarkan penghalaan?

Saya sudah tahu bahawa anda boleh mengkonfigurasi penggunaan jwt dalam fungsi httpsecurity 上使用 oauth2resourceserver(), tetapi saya hanya menemui maklumat tentang cara melaksanakan fungsi itu untuk penyewa tunggal.

Jika sesiapa telah berjaya melaksanakan kes khusus atau serupa ini, atau boleh mendorong saya ke arah yang betul, saya amat berterima kasih. Atau mungkin idea saya salah sama sekali, jadi tolong beritahu saya.

Menggunakan Kemas Kini Penyelesaian Kerja (25 Januari 2024)

Terima kasih kepada @ch4mp atas jawapannya, saya telah berjaya. >Jawapan Berfungsi

Pelaksanaan saya kini sangat dipermudahkan dan kelihatan seperti ini:

permohonan.yml

com:
  c4-soft:
    springaddons:
      oidc:
        ops:
          - iss: https://cognito-idp.<region>.amazonaws.com/<cognito-pool>
            authorities:
              - path: $.cognito:groups
                prefix: cognito_group_
          - iss: https://sts.windows.net/<entra objectid>/
            authorities:
              - path: $.roles.*
                prefix: aad_approle_
              - path: $.scp
                prefix: aad_scope_
            aud: <enterprise application id>
        resource-server:
          permit-all:
            - /api/route/noauth

Konfigurasi keselamatan

package some.package;

import org.springframework.context.annotation.configuration;
import org.springframework.security.config.annotation.method.configuration.enablemethodsecurity;
import org.springframework.security.config.annotation.web.configuration.enablewebsecurity;

@enablewebsecurity
@enablemethodsecurity
@configuration
public class securityconfig { }

Pengawal saya kini kelihatan seperti ini:

package some.package;


import org.springframework.http.responseentity;
import org.springframework.security.access.prepost.preauthorize;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.security.oauth2.jwt.jwt;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
@requestmapping("/api/route")
public class jwttestcontroller {

    @getmapping("/aadauth")
    @preauthorize("hasauthority('aad_approle_grantedapprole.xxx')")
    public responseentity<string> aadauthrole() {
        jwt jwt = (jwt) securitycontextholder.getcontext().getauthentication().getprincipal();
        return responseentity.ok(jwt.getclaims().tostring());
    }

    @getmapping("/aadauth")
    @preauthorize("hasauthority('aad_scope_grantedscope.xxx')")
    public responseentity<string> aadauthscope() {
        jwt jwt = (jwt) securitycontextholder.getcontext().getauthentication().getprincipal();
        return responseentity.ok(jwt.getclaims().tostring());
    }

    @preauthorize("hasauthority('cognito_group_somegroup')")
    @getmapping("/cognitoauth")
    public responseentity<string> cognitoauth() {
        jwt jwt = (jwt) securitycontextholder.getcontext().getauthentication().getprincipal();
        return responseentity.ok(jwt.getclaims().tostring());
    }

    @getmapping("/noauth")
    public responseentity<string> noauth() {
        return responseentity.ok("hello world!");
    }

}

build.gradle

implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
    implementation 'com.c4-soft.springaddons:spring-addons-starter-oidc:7.3.5'

Ini bukan pelancar rasmi musim bunga, tetapi pelaksanaan oss: https://www.php.cn/link/49844ba129a1cbc3d964703fcdb756ba

Saya akan mengemas kini sekali lagi jika saya menghadapi sebarang isu lain, tetapi buat masa ini ia berfungsi.

Penyelesaian

Saya akan dedahkan penyelesaian di sini menggunakan pemula saya kerana ia lebih mudah.

Jika anda memilih untuk hanya menggunakan pemula but spring "rasmi" untuk membina konfigurasi keselamatan anda, anda mesti menggunakan iss 声明提供自己的 authenticationmanagerresolver<httpservletrequest></httpservletrequest>, setiap pengurus pengesahan mempunyai penukar pengesahan sendiri dan penukar kebenaran sendiri untuk mengendalikan tuntutan sumber dan anda mahukan awalan yang diperlukan. Semak imbas tutorial saya atau dokumentasi rasmi untuk contoh dan petua pelaksanaan. Jawapan lain ini juga mungkin membantu (keperluan pemetaan kebenaran adalah berbeza sama sekali, tetapi penyelesai pengurus pengesahan adalah serupa).

Gunakan but 3.2.2 dan spring-addons

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
    xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelversion>4.0.0</modelversion>
    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>3.2.2</version>
        <relativepath/> <!-- lookup parent from repository -->
    </parent>
    <groupid>com.c4-soft.demo</groupid>
    <artifactid>multi-tenant-resource-server</artifactid>
    <version>0.0.1-snapshot</version>

    <properties>
        <java.version>21</java.version>
        <spring-addons.version>7.3.5</spring-addons.version>
    </properties>

    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-oauth2-resource-server</artifactid>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <dependency>
            <groupid>com.c4-soft.springaddons</groupid>
            <artifactid>spring-addons-starter-oidc</artifactid>
            <version>${spring-addons.version}</version>
        </dependency>

        <dependency>
            <groupid>com.c4-soft.springaddons</groupid>
            <artifactid>spring-addons-starter-oidc-test</artifactid>
            <version>${spring-addons.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>

</project>
@configuration
@enablemethodsecurity
public class securityconf {
}

Edit yang berikut application.yaml untuk menempatkan penerbit anda sendiri:

com:
  c4-soft:
    springaddons:
      oidc:
        ops:
        - iss: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_rzhmglwjl
          authorities:
          - path: $.cognito:groups
            prefix: cognito_group_
        - iss: https://sts.windows.net/0a962d63-6b23-4416-81a6-29f88c553998/
          authorities:
          - path: $.approles.*.displayname
            prefix: aad_approle_
          - path: $.scope
            prefix: aad_scope_
        resourceserver:
          # spring-addons whitelist is for permitall() (rather than isauthenticated())
          # which is probably much safer
          permit-all:
          - /actuator/health/readiness
          - /actuator/health/liveness
          - /v3/api-docs/**
          - /api/public/**

Nilai path di atas ialah laluan json. Anda boleh menggunakan alatan seperti jsonpath.com untuk menguji ungkapan laluan terhadap muatan token anda sendiri (diekstrak menggunakan alatan seperti jwt.io).

Ya, semudah itu. Tidak, saya tidak meninggalkan sebarang sifat yaml atau konfigurasi java (jika anda tidak percaya saya, hanya mengujinya dalam projek baharu).

示例控制器

@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"
}

Atas ialah kandungan terperinci Mengamankan Spring Boot REST API untuk titik akhir yang berbeza menggunakan AAD dan AWS Cognito. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:stackoverflow. Jika ada pelanggaran, sila hubungi admin@php.cn Padam

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

VSCode Windows 64-bit Muat Turun

VSCode Windows 64-bit Muat Turun

Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft