Apabila menggunakan OAuth 2.0 Resource Server JWT, anda kadangkala menghadapi masalah kebenaran (kebenaran). Ini adalah cabaran yang sering dihadapi oleh ramai pembangun semasa proses pembangunan. OAuth 2.0 ialah piawaian terbuka untuk kebenaran yang membenarkan pengguna membenarkan aplikasi pihak ketiga mengakses sumber dilindungi mereka. JWT (JSON Web Token) ialah satu cara untuk meluluskan tuntutan antara aplikasi web. Walau bagaimanapun, dalam amalan, beberapa masalah kebenaran mungkin berlaku, seperti kegagalan kebenaran, kegagalan untuk mendapatkan token akses, dsb. Artikel ini akan menganalisis isu ini dan menyediakan beberapa penyelesaian untuk membantu pembangun menggunakan pelayan sumber OAuth 2.0 JWT dengan lebih baik.
Saya cuba mengkonfigurasi kebenaran akses menggunakan pelayan sumber oauth 2.0 jwt dalam aplikasi mudah.
Seluruh bahagian pengesahan berfungsi dengan baik, tetapi saya menghadapi masalah dengan kebenaran. Semua titik akhir yang dilindungi memberikan 403 forbidden
ralat walaupun kebenaran yang betul terdapat dalam token.
Saya cuba menggunakan atribut skop lalai (scope_) dan menukar konfigurasi kepada peranan (role_) tetapi masalah berterusan.
Ada sesiapa tahu cara menyelesaikannya?
Kod sumber penuh: https://github.com/gustavosc1/spring-security-jwt
Jana contoh token: eyjhbgcioijsuzi1nij9.eyjpc3mioijzchjpbmctc2vjdxjpdhktand0iiwic3viijoidxnlcm5hbwuilcjlehaioje3mdu0ndmyotqsimtlhdcm x0fe tuloin0.peivwrthx_7mr6eefqbid5dplhffzcvd7scmmt3f7rk7sk1i6kerpqi5ubdvaefnzsjq6vka5nadltsbqidfzogmoixjktfhsc5zrnyyrhikvnwcwb3wrgfjxzwdd1wrgfjxzwk a b5qnan07fjpvslk--ccsg
Konfigurasi keselamatan:
@configuration @enablewebsecurity //@enablemethodsecurity(prepostenabled = true) public class securityconfig { @value("${jwt.public.key}") private rsapublickey key; @value("${jwt.private.key}") private rsaprivatekey priv; @bean securityfilterchain filterchain(httpsecurity http) throws exception { http.csrf(csrf -> csrf.disable()) .authorizehttprequests( auth -> auth .requestmatchers("/authenticate").permitall() .requestmatchers("/register").permitall() .requestmatchers("/private").hasanyrole("admin")) .httpbasic(customizer.withdefaults()) // https://docs-spring-io.translate.goog/spring-security/reference/servlet/oauth2/resource-server/jwt.html?_x_tr_sl=en&_x_tr_tl=pt&_x_tr_hl=pt-br&_x_tr_pto=sc .oauth2resourceserver( conf -> conf.jwt( jwt -> jwt.decoder(jwtdecoder()) .jwtauthenticationconverter(jwtauthenticationconverter()))); return http.build(); } @bean public jwtauthenticationconverter jwtauthenticationconverter() { jwtgrantedauthoritiesconverter grantedauthoritiesconverter = new jwtgrantedauthoritiesconverter(); grantedauthoritiesconverter.setauthoritiesclaimname("roles"); grantedauthoritiesconverter.setauthorityprefix("role_"); jwtauthenticationconverter jwtauthenticationconverter = new jwtauthenticationconverter(); jwtauthenticationconverter.setjwtgrantedauthoritiesconverter(grantedauthoritiesconverter); return jwtauthenticationconverter; } @bean jwtdecoder jwtdecoder() { return nimbusjwtdecoder.withpublickey(this.key).build(); } @bean jwtencoder jwtencoder() { jwk jwk = new rsakey.builder(this.key).privatekey(this.priv).build(); jwksource<securitycontext> jwks = new immutablejwkset<>(new jwkset(jwk)); return new nimbusjwtencoder(jwks); } @bean passwordencoder passwordencoder() { return new bcryptpasswordencoder(); } }
userdetailsserviceimpl:
@service public class userdetailsserviceimpl implements userdetailsservice { private final userrepository userrepository; public userdetailsserviceimpl(userrepository userrepository) { this.userrepository = userrepository; } @override public userdetails loaduserbyusername(string username) throws usernamenotfoundexception { optional<user> useroptional = userrepository.findbyusername(username); user user = useroptional.orelsethrow(() -> new usernamenotfoundexception("user not found with username: " + username)); return new userauthenticated(user.getusername(), user.getpassword()); } }
Pengguna disahkan:
public class userauthenticated implements userdetails { private string username; private string password; public userauthenticated(string username, string password) { this.username = username; this.password = password; } @override public string getusername() { return username; } @override public string getpassword() { return password; } @override public collection<? extends grantedauthority> getauthorities() { return list.of(() -> "role_admin"); } @override public boolean isaccountnonexpired() { return true; } @override public boolean isaccountnonlocked() { return true; } @override public boolean iscredentialsnonexpired() { return true; } @override public boolean isenabled() { return true; } }
jwtservice:
@service public class jwtservice { private final jwtencoder encoder; public jwtservice(jwtencoder encoder) { this.encoder = encoder; } public string generatetoken(authentication authentication) { instant now = instant.now(); long expiry = 36000l; string scope = authentication .getauthorities().stream() .map(grantedauthority::getauthority) .collect(collectors .joining(" ")); jwtclaimsset claims = jwtclaimsset.builder() .issuer("spring-security-jwt") .issuedat(now) .expiresat(now.plusseconds(expiry)) .subject(authentication.getname()) .claim("roles", scope) .build(); return encoder.encode( jwtencoderparameters.from(claims)) .gettokenvalue(); } }
Pengawal Persendirian:
@RestController @RequestMapping("private") public class PrivateController { @GetMapping //@PreAuthorize("hasAuthority('ROLE_ADMIN')") public String getMessage() { return "Hello from private API controller"; } }
telah menjana token dan akan roles
字段设置为 ROLE_ADMIN
。在 jwtAuthenticationConverter()
中,您尝试将 setAuthorityPrefix
与 ROLE
一起使用,导致 ROLE_ROLE_ADMIN
yang disediakan.
Untuk membetulkan masalah ini, tukar talian kepada grantedAuthoritiesConverter.setAuthorityPrefix("");
.
Selepas membuat pelarasan ini, masalah harus diselesaikan. Jika anda menghadapi sebarang masalah lain sila beritahu saya.
Perhatian:
Jika anda meninggalkan langkah ini, awalan lalai ialah SCOPE
,导致您的角色变为 SCOPE_ROLE_ADMIN
.
Atas ialah kandungan terperinci Isu Kebenaran (Kebenaran) Menggunakan Pelayan Sumber OAuth 2.0 JWT. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!