Class DefaultAuthPrincipal

java.lang.Object
org.springframework.security.core.userdetails.User
io.leandev.appfuse.security.auth.DefaultAuthPrincipal
All Implemented Interfaces:
AuthPrincipal, TenantAwareUserDetails, Serializable, org.springframework.security.core.CredentialsContainer, org.springframework.security.core.userdetails.UserDetails

public class DefaultAuthPrincipal extends org.springframework.security.core.userdetails.User implements AuthPrincipal, TenantAwareUserDetails

AuthPrincipal 的預設實作——UserDetailsService 把自家帳號攤平成引擎主體的便利類

對齊 Spring Security 自身的模式:介面 UserDetails + 具體便利類 User;此處是 AuthPrincipal + 本類。帳號 entity 不應實作 UserDetails(會把持久化物件圖與密碼 拖進 SecurityContext),一律由 UserDetailsService 轉接——本類即那個轉接產物。

承載的恰好是引擎會讀的東西,不多不少:

成員 來源契約 誰讀
username / password / authorities / 四個旗標 UserDetails(繼承 User DaoAuthenticationProvider@PreAuthorize
tenantId TenantAwareUserDetails LoginService 簽 tenant claim、UserDetailsTenantIdResolver
interactiveLoginAllowed AuthPrincipal LoginService 的登入/刷新資格判定

吃判定結果、不吃帳號分類概念——interactiveLoginAllowed 由消費端自行導出 (參考實作為 !account.isServiceAccount());jar 不認識「服務帳號」這類分類。

需要在主體上多帶欄位(如帳號 id、部門)時繼承本類即可;引擎不受影響。

return DefaultAuthPrincipal.builder(account.getUsername())
        .password(account.getPassword())
        .authorities(authorities)
        .enabled(account.isEnabled())
        .tenantId(account.getTenantId())                        // 無租戶部署省略
        .interactiveLoginAllowed(!account.isServiceAccount())
        .build();
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 

    Nested classes/interfaces inherited from class org.springframework.security.core.userdetails.User

    org.springframework.security.core.userdetails.User.UserBuilder
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    DefaultAuthPrincipal.Builder 建構;子類可經此建構子擴充
  • Method Summary

    Modifier and Type
    Method
    Description
    builder(String username)
    開始建構主體
    所屬租戶;null = 無租戶(引擎不簽 tenant claim)
    boolean
    本主體可否使用互動式登入/刷新
    Token 與 session 使用的穩定主體識別。

    Methods inherited from class org.springframework.security.core.userdetails.User

    builder, equals, eraseCredentials, getAuthorities, getPassword, getUsername, hashCode, isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled, toString, withDefaultPasswordEncoder, withUserDetails, withUsername

    Methods inherited from class Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait

    Methods inherited from interface org.springframework.security.core.userdetails.UserDetails

    getAuthorities, getPassword, getUsername, isAccountNonExpired, isAccountNonLocked, isCredentialsNonExpired, isEnabled
  • Constructor Details

  • Method Details

    • builder

      public static DefaultAuthPrincipal.Builder builder(String username)
      開始建構主體
      Parameters:
      username - 登入身分識別子
    • subject

      public String subject()
      Description copied from interface: AuthPrincipal

      Token 與 session 使用的穩定主體識別。

      預設沿用 UserDetails.getUsername() 以維持既有實作相容;當登入名稱不是全域唯一 (例如同一 username 可存在於多個 tenant)時,應用應回傳不可變的 account id。 顯示用 username 仍屬應用 wire model,不應拿來當 JWT sub

      Specified by:
      subject in interface AuthPrincipal
    • getTenantId

      public String getTenantId()
      所屬租戶;null = 無租戶(引擎不簽 tenant claim)
      Specified by:
      getTenantId in interface TenantAwareUserDetails
      Returns:
      租戶 ID,若使用者不屬於任何租戶則可返回 null
    • interactiveLoginAllowed

      public boolean interactiveLoginAllowed()
      Description copied from interface: AuthPrincipal

      本主體可否使用互動式登入/刷新

      「服務帳號(M2M)不可互動登入」這類資格判定的一般化——引擎不認識任何具體的帳號 分類概念,只問這個判定結果。引擎保留拒絕原因,HTTP 揭露程度由 ErrorDisclosurePolicy 決定。

      Specified by:
      interactiveLoginAllowed in interface AuthPrincipal
      Returns:
      true 允許互動式登入與刷新(預設);false 拒絕