我正在尝试通过 jakarta 持久性获得基本身份验证,以便与 quarkus REST 服务一起使用。我按照 https://quarkus.io/guides/security-basic-authentication-tutorial 上的说明进行操作,但在自定义密码提供程序中遇到了问题。
相关代码如下:
用户:
@Entity
@Table(name = "pwd_table")
@UserDefinition
public class LoginUser {
@Id
@Column(name = "USERID")
public Long userid;
@Column(name = "USERNAME")
@Username
public String username;
@Column(name = "PWD_CRYPT")
@Password(value = PasswordType.CUSTOM, provider = CustomPasswordProvider.class)
public String password;
@Roles
public String roles;
}
密码提供者
public class CustomPasswordProvider implements PasswordProvider {
public CustomPasswordProvider() {
}
@Override
public org.wildfly.security.password.Password getPassword(String pass) {
byte[] digest = MyHash.hash(pass) // simplified code, we use SCrypt here...
return SimpleDigestPassword.createRaw("myhash", digest);
}
}
@GET
@RolesAllowed("backoffice")
@Path("/{myId}")
@Produces(MediaType.APPLICATION_XML)
public Response getXML(@PathParam("myId") String myId) {
...
}
我的期望是,http 请求标头中提供的密码被传递到 PasswordProvider 类中的 getPassword 方法,以便对该明文密码进行哈希处理,并将其与存储在数据库中用于身份验证的哈希密码进行比较过程。
发生的情况是,来自数据库的散列密码被传递到PasswordProvider,并在那里再次进行散列,这是没有意义的。身份验证当然失败了(401 Unauthorized)。
可能我误解了一些东西,但我在网上找不到解决方案。
我的做法显然是错误的。正如错误报告中的讨论所指出的,该文档有点误导她https://github.com/quarkusio/quarkus/issues/35671。
正确的方法是自定义 IdentityProvider: