Quarkus SecurityとJakarta Persistence
Jakarta Persistence を使用してユーザーのIDを保存するように、アプリケーションを設定できます。
Quarkusは、 JDBC IDプロバイダー と同様に、Jakarta Persistence IDプロバイダーを提供します。Jakarta Persistenceは、ユーザー名とパスワードのクレデンシャルを必要とする、 Basic 認証 と フォームベース のQuarkus Security認証メカニズムでの使用に適しています。
Jakarta Persistence IdentityProvider は SecurityIdentity インスタンスを作成します。ユーザー認証中、このインスタンスはアクセス要求の検証と認可に使用されます。
具体的な例については、 Basic 認証と Jakarta Persistence を使用したセキュリティの開始 チュートリアルを参照してください。
Jakarta Persistence エンティティの仕様
Quarkus Securityは、ユーザー名、パスワード、ロールを収集し、Jakarta Persistenceデータベースエンティティに格納するためのJakarta Persistence統合を提供します。
次のJakarta Persistenceエンティティの仕様は、Quarkusがデータベースからこの情報を取得できるよう、ユーザーの情報をJakarta Persistenceエンティティに格納し、正しくマッピングする必要がある方法を示しています。
-
@UserDefinitionアノテーションは、 簡略化されたHibernate ORM with Panache が使用されているかどうかにかかわらず、Jakarta Persistenceエンティティに存在する必要があります。 -
@Usernameおよび@Passwordフィールドの型は常にStringです。 -
@Rolesフィールドは、String、Collection<String>、またはCollection<X>のいずれかである必要があります。ここでXは、@RolesValueとしてアノテーションされた単一のStringフィールドを持つエンティティクラスです。 -
各
Stringロール要素の型は、コンマ区切りのロールのリストとしてパースされます。
次の例は、 user エンティティにアノテーションを追加することでセキュリティ情報を保存する方法を示しています。
package org.acme.security.jpa;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import io.quarkus.hibernate.orm.panache.PanacheEntity;
import io.quarkus.elytron.security.common.BcryptUtil;
import io.quarkus.security.jpa.Password;
import io.quarkus.security.jpa.Roles;
import io.quarkus.security.jpa.UserDefinition;
import io.quarkus.security.jpa.Username;
@Entity
@Table(name = "test_user") (1)
@UserDefinition (2)
public class User extends PanacheEntity {
@Username (3)
public String username;
@Password (4)
public String password;
@Roles (5)
public String role;
/**
* Adds a new user to the database
* @param username the username
* @param password the unencrypted password (it is encrypted with bcrypt)
* @param role the comma-separated roles
*/
public static void add(String username, String password, String role) { (6)
User user = new User();
user.username = username;
user.password = BcryptUtil.bcryptHash(password);
user.role = role;
user.persist();
}
}
quarkus-security-jpa エクステンションは、単一のエンティティに @UserDefinition アノテーションが付与されている場合にのみ初期化されます。
| 1 | テーブル名。ほとんどのデータベースで制限されているキーワードである user として定義しないでください。 |
| 2 | @UserDefinition アノテーションは、通常の Hibernate ORM エンティティ、または Panache を使用する Hibernate ORM エンティティのいずれか、単一のエンティティに存在する必要があります。 |
| 3 | ユーザー名に使用されるフィールドを示します。 |
| 4 | パスワードに使用されるフィールドを示します。デフォルトでは、 quarkus-security-jpa は bcryptでハッシュされたパスワードを使用しますが、代わりにプレーンテキストまたはカスタムパスワードを設定することもできます。 |
| 5 | これは、対象のプリンシパル表現属性に追加された、コンマ区切りのロールのリストを示します。 |
| 6 | このメソッドを使用すると、適切な bcrypt ハッシュでパスワードをハッシュしながらユーザーを追加できます。 |
ロールの保存先としてのJakarta Persistenceエンティティ
次の例を使用して、ロールを別のJakarta Persistenceエンティティ内に格納します。
@UserDefinition
@Table(name = "test_user")
@Entity
public class User extends PanacheEntity {
@Username
public String name;
@Password
public String pass;
@ManyToMany
@Roles
public List<Role> roles = new ArrayList<>();
}
@Entity
public class Role extends PanacheEntity {
@ManyToMany(mappedBy = "roles")
public List<User> users;
@RolesValue
public String role;
}
|
この例は、ロールの保存とアクセスを示しています。既存のユーザーを更新したり、新しいユーザーを作成したりするには、 |
パスワードの保存とハッシュ化
Quarkusでアプリケーションを開発する場合、パスワードの保存とハッシュ化の管理方法を決定できます。Quarkusのデフォルトのパスワードとハッシュ設定を維持することも、手動でパスワードをハッシュ化することも可能です。
デフォルトのオプションでは、パスワードは bcrypt を使用して、 Modular Crypt Format (MCF) の下で保存およびハッシュ化されます。MCFを使用している間は、ハッシュアルゴリズム、反復回数、およびソルトがハッシュ値の一部として保存されます。そのため、それらを保持するための専用のカラムは必要ありません。
|
暗号化において、ソルトとは、データ、パスワード、またはパスフレーズをハッシュ化する一方向関数への追加入力として使用されるランダムなデータの名前です。 |
異なるアルゴリズムでハッシュ化されたデータベースに保存されているパスワードを表現するには、次の例に示すように org.wildfly.security.password.PasswordProvider を実装するクラスを作成します。
次のスニペットは、SHA256ハッシュアルゴリズムでハッシュ化されたパスワードを表すカスタムパスワードプロバイダを設定する方法を示しています。
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import io.quarkus.security.jpa.Password;
import io.quarkus.security.jpa.PasswordType;
import io.quarkus.security.jpa.Roles;
import io.quarkus.security.jpa.UserDefinition;
import io.quarkus.security.jpa.Username;
@UserDefinition
@Table(name = "test_user")
@Entity
public class CustomPasswordUserEntity {
@Id
@GeneratedValue
public Long id;
@Column(name = "username")
@Username
public String name;
@Column(name = "password")
@Password(value = PasswordType.CUSTOM, provider = CustomPasswordProvider.class)
public String pass;
@Roles
public String role;
}
import jakarta.xml.bind.DatatypeConverter;
import org.wildfly.security.password.Password;
import org.wildfly.security.password.interfaces.SimpleDigestPassword;
import io.quarkus.security.jpa.PasswordProvider;
public class CustomPasswordProvider implements PasswordProvider {
@Override
public Password getPassword(String passwordInDatabase) {
byte[] digest = DatatypeConverter.parseHexBinary(passwordInDatabase);
// Let the security runtime know that this passwordInDatabase is hashed by using the SHA256 hashing algorithm
return SimpleDigestPassword.createRaw(SimpleDigestPassword.ALGORITHM_SIMPLE_DIGEST_SHA_256, digest);
}
}
|
ハッシュ化されたパスワードを素早く作成するには、 |
|
本番環境で実行されるアプリケーションでは、パスワードをプレーンテキストで保存しないでください。 ただし、テスト環境で運用する場合は、 |
|
Hibernate マルチテナンシー がサポートされており、マルチテナンシーが有効な永続ユニットにユーザーエンティティを格納できます。ただし、 |
ビルド時に固定される設定プロパティー - 他のすべての設定プロパティーは実行時にオーバーライド可能
Configuration property |
型 |
デフォルト |
|---|---|---|
Selects the Hibernate ORM persistence unit. Default persistence unit is used when no value is specified. Environment variable: Show more |
string |