Quarkus SecurityとJakarta Persistence
ユーザのIDを保存するために、jakarta Persistenceを使用するようにアプリケーションを設定できます。
Quarkusは、 JDBC IDプロバイダー と同様に、Jakarta Persistence IDプロバイダーを提供します。Jakarta Persistenceは、ユーザー名とパスワードのクレデンシャルを必要とする、 Basic および フォームベース のQuarkus Securityメカニズムでの使用に適しています。
Jakarta Persistence IdentityProvider
は、 SecurityIdentity
インスタンスを作成します。ユーザ認証の際、このインスタンスはアクセス要求の検証と認可に使用されます。
実用的な例については、チュートリアル Basic認証 とJakarta PersistenceによるQuarkus Security入門 を参照してください。
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")
@UserDefinition (1)
public class User extends PanacheEntity {
@Username (2)
public String username;
@Password (3)
public String password;
@Roles (4)
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) { (5)
User user = new User();
user.username = username;
user.password = BcryptUtil.bcryptHash(password);
user.role = role;
user.persist();
}
}
The quarkus-security-jpa
extension initializes only if a single entity is annotated with @UserDefinition
.
1 | The @UserDefinition annotation must be present on a single entity, either a regular Hibernate ORM entity or a Hibernate ORM with Panache entity. |
2 | ユーザー名に使用するフィールドを示します。 |
3 | Indicates the field used for the password.
By default, quarkus-security-jpa uses bcrypt-hashed passwords, or you can configure plain text or custom passwords instead. |
4 | ここでは対象のプリンシパル表現属性に追加されたロールのコンマ区切りリストを示します。 |
5 | この方法では、適切な 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 で モジュラー暗号フォーマット (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);
}
}
ハッシュ化されたパスワードを素早く作成するには、 |
本番環境で動作するアプリケーションでは、パスワードをプレーンテキストとして保存しないでください。 ただし、テスト環境で運用する場合は、 |
The Hibernate Multitenancy is supported, and you can store the user entity in a persistence unit with enabled multitenancy.
However, if your |
ビルド時に固定される構成プロパティ - 他のすべての構成プロパティは実行時にオーバーライド可能
Configuration property |
型 |
デフォルト |
---|---|---|
Selects the Hibernate ORM persistence unit. Default persistence unit is used when no value is specified. Environment variable: Show more |
string |
|