Pengesahan JWT Pelayan Sumber dan Tuntutan
Sahkan token akses JWT, sahkan penerbit serta khalayak dan ekstrak autoriti daripada tuntutan.
Pengesahan JWT Pelayan Sumber dan Tuntutan ialah pelajaran Panduan Lengkap Spring Boot 4 percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Panduan Lengkap Spring Boot 4, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.
Peranan Pelayan Sumber
Dalam OAuth2, pelayan sumber ialah API yang menyimpan data yang dilindungi. Pelayan ini tidak melog masuk pengguna atau mengeluarkan token. Tugasnya pada waktu permintaan hanyalah mengesahkan token akses yang telah dikeluarkan oleh pelayan keizinan, kemudian membenarkan panggilan tersebut.
- Token biasanya ialah JWT (JSON Web Token) yang ditandatangani oleh pelayan keizinan.
- Pengesahan tidak berkeadaan: pelayan sumber mengesahkan tandatangan dan tuntutan tanpa memanggil pangkalan data.
- Spring Security menyediakan DSL
oauth2ResourceServerkhusus untuk tujuan ini.
Dalam pelajaran ini, anda akan mengesahkan JWT, mengesahkan tuntutan iss dan aud, serta menukar tuntutan kepada keizinan Spring.
Anatomi JWT
JWT mempunyai tiga bahagian Base64URL yang dipisahkan oleh titik: header.payload.signature. Muatan membawa tuntutan yang diperiksa oleh pelayan sumber:
iss— penerbit, iaitu URL pelayan keizinan.sub— subjek, iaitu id pengguna atau klien.aud— khalayak, iaitu pihak yang dimaksudkan untuk menerima token.exp/nbf/iat— cap masa luput, belum sah sebelum dan dikeluarkan pada.scopeatauscp— skop OAuth2 yang diberikan.
Contoh di bawah menunjukkan rupa muatan yang dinyahkod sebagai JSON biasa. Pengesahan bermaksud: tandatangan adalah tulen DAN tuntutan ini boleh diterima.
// A decoded JWT payload (claims) as JSON
{
"iss": "https://issuer.example.com",
"sub": "user-1234",
"aud": ["orders-api"],
"scope": "orders.read orders.write",
"roles": ["ADMIN", "USER"],
"iat": 1735689600,
"nbf": 1735689600,
"exp": 1735693200
}Konfigurasi Minimum Pelayan Sumber
Dengan spring-boot-starter-oauth2-resource-server pada classpath, anda mengaktifkan pengesahan JWT melalui DSL keselamatan. Pengkonfigurasi jwt() menyambungkan pengesahan tandatangan dan pemeriksaan cap masa standard secara automatik.
Arahkan Spring kepada metadata pelayan keizinan melalui URI penerbit, lalu Spring akan menemukan titik akhir Set JWK (kunci awam) dengan sendiri.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health").permitAll()
.anyRequest().authenticated())
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(Customizer.withDefaults()));
return http.build();
}
}Mengkonfigurasi URI Penerbit
Cara paling kemas untuk menyediakan konfigurasi ialah menggunakan sifat issuer-uri. Semasa permulaan, Spring mengambil {issuer}/.well-known/openid-configuration (atau padanan OAuth2), membaca jwks_uri, lalu membina JwtDecoder yang menyimpan dan memutarkan kunci tandatangan.
Spring juga memasang pengesah penerbit: tuntutan iss bagi setiap token mestilah sama dengan nilai ini, jika tidak token tersebut ditolak.
# application.yml
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://issuer.example.com
# Optional: pin the audience(s) accepted by this API
audiences:
- orders-apiCara JwtDecoder Mengesahkan
Apabila issuer-uri ditetapkan, Spring membina NimbusJwtDecoder yang disokong oleh Set JWK yang ditemui. Setiap token masuk melalui langkah berikut:
- Semakan tandatangan —
kidtoken memilih kunci awam daripada Set JWK; tandatangan mestilah sah. - Semakan cap masa —
expmestilah pada masa hadapan, manakalanbfmestilah pada masa lalu (dengan sedikit perbezaan jam yang dibenarkan). - Semakan penerbit —
issmestilah sepadan dengan penerbit yang dikonfigurasi.
Anda boleh membina penyahkod yang sama secara manual apabila perlu melampirkan pengesah tambahan.
@Bean
JwtDecoder jwtDecoder() {
String issuer = "https://issuer.example.com";
NimbusJwtDecoder decoder =
JwtDecoders.fromIssuerLocation(issuer);
OAuth2TokenValidator<Jwt> withIssuer =
JwtValidators.createDefaultWithIssuer(issuer);
decoder.setJwtValidator(withIssuer);
return decoder;
}Mengesahkan Tuntutan Khalayak
Pengesah lalai menyemak cap masa dan penerbit, tetapi bukan khalayak. Melangkau semakan aud ialah risiko sebenar: token yang dikeluarkan untuk API lain pada penerbit yang sama akan diterima di sini. Inilah serangan kekeliruan token klasik.
Tulis OAuth2TokenValidator<Jwt> tersuai yang memastikan pengecam API anda terdapat dalam senarai aud, kemudian rangkaikannya dengan pengesah lalai.
public class AudienceValidator
implements OAuth2TokenValidator<Jwt> {
private final String audience;
public AudienceValidator(String audience) {
this.audience = audience;
}
@Override
public OAuth2TokenValidatorResult validate(Jwt jwt) {
if (jwt.getAudience().contains(audience)) {
return OAuth2TokenValidatorResult.success();
}
OAuth2Error error = new OAuth2Error(
OAuth2ErrorCodes.INVALID_TOKEN,
"Required audience is missing", null);
return OAuth2TokenValidatorResult.failure(error);
}
}Merangkaikan Pengesah dalam Penyahkod
Gabungkan pengesah khalayak dengan rangkaian lalai bersama penerbit menggunakan DelegatingOAuth2TokenValidator. Susunan tidak penting dari segi ketepatan — semua pengesah mesti lulus — tetapi kekalkan semakan tandatangan dan cap masa (dikendalikan secara dalaman) bersama-sama semakan penerbit dan khalayak.
Bean penyahkod ini mengatasi bean yang dikonfigurasikan secara automatik sambil terus menggunakan semula kunci JWK yang ditemui.
@Bean
JwtDecoder jwtDecoder(
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuer,
@Value("${api.audience}") String audience) {
NimbusJwtDecoder decoder =
JwtDecoders.fromIssuerLocation(issuer);
OAuth2TokenValidator<Jwt> validator =
new DelegatingOAuth2TokenValidator<>(
JwtValidators.createDefaultWithIssuer(issuer),
new AudienceValidator(audience));
decoder.setJwtValidator(validator);
return decoder;
}Daripada Skop kepada Autoriti
Secara lalai, Spring memetakan tuntutan scope (atau scp) kepada autoriti, dengan menambahkan awalan SCOPE_ pada setiap satunya. Jadi scope: "orders.read" menjadi autoriti SCOPE_orders.read, yang boleh anda wajibkan dalam DSL atau dengan keselamatan kaedah.
hasAuthority("SCOPE_orders.read")dalamauthorizeHttpRequests.@PreAuthorize("hasAuthority('SCOPE_orders.write')")pada sesuatu kaedah.
Lalai ini berfungsi terus tanpa memerlukan penukar.
http.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.GET, "/orders/**")
.hasAuthority("SCOPE_orders.read")
.requestMatchers(HttpMethod.POST, "/orders/**")
.hasAuthority("SCOPE_orders.write")
.anyRequest().authenticated());Mengekstrak Peranan daripada Tuntutan Tersuai
Banyak pembekal identiti (Keycloak, Auth0, Entra ID) meletakkan peranan dalam tuntutan bukan standard seperti roles atau realm_access.roles, bukannya dalam scope. Untuk memetakan tuntutan ini, berikan JwtAuthenticationConverter dengan fungsi seakan-akan JwtGrantedAuthoritiesConverter tersuai.
Di sini, kami membaca tatasusunan roles peringkat atas dan menghasilkan autoriti berawalan ROLE_ supaya hasRole(...) berfungsi.
@Bean
JwtAuthenticationConverter jwtAuthConverter() {
JwtAuthenticationConverter converter =
new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt -> {
List<String> roles =
jwt.getClaimAsStringList("roles");
if (roles == null) return List.of();
return roles.stream()
.map(r -> new SimpleGrantedAuthority("ROLE_" + r))
.collect(Collectors.toList());
});
return converter;
}Menyambungkan Penukar dan Membaca Tuntutan
Daftarkan penukar pada DSL pelayan sumber supaya ia digunakan untuk membina Authentication. Setelah disambungkan, pengawal anda boleh menyuntik Jwt yang telah disahkan dan membaca sebarang tuntutan secara terus — tuntutan itu telah disahkan sebelum pengendali dijalankan.
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain chain(HttpSecurity http,
JwtAuthenticationConverter converter) throws Exception {
http.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(converter)));
return http.build();
}
}
@RestController
class MeController {
@GetMapping("/me")
Map<String, Object> me(@AuthenticationPrincipal Jwt jwt) {
return Map.of(
"sub", jwt.getSubject(),
"issuer", jwt.getIssuer().toString(),
"roles", jwt.getClaimAsStringList("roles"));
}
}Membina Autoriti dalam Java Biasa
Logik pemetaan peranan hanyalah transformasi data — logik yang sama dijalankan oleh penukar, tanpa rangka kerja. Petikan di bawah ialah program kendiri yang menunjukkan cara menukar nilai tuntutan kepada autoriti berawalan ROLE_ dan SCOPE_, sama seperti lalai Spring.
import java.util.*;
import java.util.stream.*;
public class AuthorityMapping {
static List<String> fromRoles(List<String> roles) {
return roles.stream()
.map(r -> "ROLE_" + r)
.collect(Collectors.toList());
}
static List<String> fromScope(String scope) {
return Arrays.stream(scope.split(" "))
.filter(s -> !s.isBlank())
.map(s -> "SCOPE_" + s)
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<String> authorities = new ArrayList<>();
authorities.addAll(fromRoles(List.of("ADMIN", "USER")));
authorities.addAll(fromScope("orders.read orders.write"));
System.out.println(authorities);
}
}Semakan Pantas
Pelayan sumber anda menggunakan issuer-uri, jadi tandatangan, tamat tempoh dan penerbit disahkan secara automatik. Seorang penguji penembusan menghantar token yang sah dan belum tamat tempoh, yang dikeluarkan oleh pelayan kebenaran yang sama tetapi dibuat untuk API yang berbeza. Titik akhir anda menerimanya. Apakah pembetulannya?
Imbas Kembali
Anda telah mengkonfigurasi pelayan sumber Spring Boot 4 untuk mengesahkan token akses JWT dari hujung ke hujung:
- URI penerbit menemui Set JWK secara automatik dan memasang pengesahan tandatangan, cap masa serta penerbit.
- Khalayak mesti disemak secara jelas dengan
OAuth2TokenValidator<Jwt>tersuai untuk menyekat kekeliruan token — lalai tidak melakukannya. - Rangkaian pengesah melalui
DelegatingOAuth2TokenValidatorsupaya penerbit + khalayak + lalai semuanya digunakan. - Autoriti datang daripada tuntutan
scopesebagaiSCOPE_*secara lalai;JwtAuthenticationConvertermemetakan tuntutan tersuai sepertiroleskepadaROLE_*. - Pengawal membaca tuntutan yang telah disahkan melalui
@AuthenticationPrincipal Jwt.
Sahkan tandatangan, kemudian jangan percayai tuntutan yang belum anda sahkan secara jelas.
Pelajari Java dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 21
- Pelajaran
- 84
Soalan Lazim
Adakah pelajaran “Pengesahan JWT Pelayan Sumber dan Tuntutan” percuma?
Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Panduan Lengkap Spring Boot 4, termasuk “Pengesahan JWT Pelayan Sumber dan Tuntutan”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Pengesahan JWT Pelayan Sumber dan Tuntutan”?
Sahkan token akses JWT, sahkan penerbit serta khalayak dan ekstrak autoriti daripada tuntutan. Anda berlatih Panduan Lengkap Spring Boot 4 menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Panduan Lengkap Spring Boot 4?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Panduan Lengkap Spring Boot 4 di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.
Berapa lamakah pelajaran “Pengesahan JWT Pelayan Sumber dan Tuntutan” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Panduan Lengkap Spring Boot 4 ini?
Ya. Setiap pelajaran Panduan Lengkap Spring Boot 4 menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Pengesahan JWT Pelayan Sumber dan Tuntutan
- Klien OAuth2 dan Aliran Kod Keizinan
- Keselamatan Kaedah dengan SpEL dan Pengundi Tersuai
- Pemeriksaan Token Legap dan Pertukaran Token