目錄
問題內容
首頁 Java 使用 OAuth 2.0 資源伺服器 JWT 時出現權限(授權)問題

使用 OAuth 2.0 資源伺服器 JWT 時出現權限(授權)問題

Feb 13, 2024 pm 03:51 PM

在使用 OAuth 2.0 資源伺服器 JWT 時,有時會遇到權限(授權)問題。這是許多開發人員在開發過程中經常遇到的挑戰。 OAuth 2.0 是一種用於授權的開放標準,它允許使用者授權第三方應用程式存取其受保護的資源。 JWT(JSON Web Token)是一種用於在網路應用程式之間傳遞聲明的方式。然而,在實務中,可能會出現一些權限問題,例如授權失敗、無法取得存取權杖等。本文將針對這些問題進行解析,並提供一些解決方案,幫助開發人員更好地使用 OAuth 2.0 資源伺服器 JWT。

問題內容

我正在嘗試使用 oauth 2.0 資源伺服器 jwt 在一個簡單的應用程式中使用 jwt 設定存取授權。

整個身份驗證部分工作正常,但我在授權方面遇到問題。即使令牌中存在正確的權限,所有受保護的端點也會給予 403 forbidden 錯誤。

我嘗試使用預設範圍(scope_)屬性並將配置更改為角色(role_),但問題仍然存在。

有誰知道怎麼解決嗎?

完整原始碼: https://github.com/gustavosc1/spring-security-jwt

產生代幣範例: eyjhbgcioijsuzi1nij9.eyjpc3mioijzchjpbmctc2vjdxjpdhktand0iiwic3ljoidxnlcm5hbwuilcjlehaioje3mdu0ndmyqxdwniiFw^motcaiwoodiwoodiwoo; eefqbid5dplhffzcvd7scmmt3f7rk7sk1i6kerpqi5ubdvaefnzsjq6vka5nadltsbqidfzogmoixjktfhsc5zrnyyrhikvnwcwb3wrgdd1gihaldfjktfhsc5zrnyyrhikvnwcwb3wrgdd1m zk3gqw42uecib9h1rrlkx9pdk7pf9rtfssfcwc-ntvismrycreco9rialqfydpdzeojimcbqveyboqfhn2woepgdm8mr5zsdhgdq e1ivsibbcj_0486zuzuqik>p25zsdhgd

安全性設定:#

@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());
  }

}
登入後複製

用戶已驗證:#

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();
  }

}
登入後複製

私人控制器:#

@RestController
@RequestMapping("private")
public class PrivateController {

  @GetMapping
  //@PreAuthorize("hasAuthority('ROLE_ADMIN')")
  public String getMessage() {
    return "Hello from private API controller";
  }
  
}
登入後複製

解決方法

已產生提供的令牌,並將

roles 欄位設為 ROLE_ADMIN。在 jwtAuthenticationConverter() 中,您嘗試將 setAuthorityPrefixROLE 一起使用,導致 ROLE_ROLE_ADMIN

要修正此問題,請將該行修改為

grantedAuthoritiesConverter.setAuthorityPrefix("");

進行此調整後,問題應該得到解決。如果您遇到任何其他問題,請告訴我。

注意:

如果省略此步驟,預設前綴將為

SCOPE,導致您的角色變為 SCOPE_ROLE_ADMIN

以上是使用 OAuth 2.0 資源伺服器 JWT 時出現權限(授權)問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)