如何在生成新密码哈希时为我的应用程序容器使用相同的凭据处理程序配置?

时间:2015-05-27 18:56:35

标签: java tomcat java-ee

我的Web应用程序的上下文定义类似于

<Context>
    <Realm className="org.apache.catalina.realm.JDBCRealm" driverName="com.microsoft.sqlserver.jdbc.SQLServerDriver" connectionURL="jdbc:sqlserver://greensuite.database.windows.net:1433;database=greensuite_db;user=greensuiteapp@greensuite;password=K1B&amp;i9i8*1id^dUzhsv^;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;" userTable="[User]" userNameCol="email" userCredCol="password" userRoleTable="UserGlobalRole" roleNameCol="role">
       <CredentialHandler className="org.apache.catalina.realm.MessageDigestCredentialHandler" encoding="UTF-8" algorithm="SHA-512" iterations="1000000" saltLength="20" />
    </Realm>
</Context>

我可以在动作监听器中放置什么,以便能够执行以下操作:

String passwordHash = credentialHandler.mutate(newPassword);

其中credentialHandler是适用于正在处理的请求的CredentialHandler实例。

重点是将配置放在一个地方,即上下文配置,而不是在上下文配置和代码生成并存储新散列中复制配置。

1 个答案:

答案 0 :(得分:0)

基本上你需要遵循克里斯托弗舒尔茨slides from ApacheCon 2016中给出的指示。假设您不反对在构建过程中引用Tomcat 8.x catalina.jar,首先import所需的类:

import javax.servlet.ServletContext;
import org.apache.catalina.CredentialHandler;
import org.apache.catalina.Globals;

然后,获取CredentialHandler只需使用正确的密钥来查找ServletContext的属性:

public static CredentialHandler getCredentialHandler(final ServletContext context) {
  return (CredentialHandler) context.getAttribute(Globals.CREDENTIAL_HANDLER);
}

幻灯片提供了一种使用反射的替代方法,以避免在编译类路径中包含catalina.jar

小心虽然这只有在您的<Realm>中配置了一个未经修改的context.xml时才有效。例如,如果您使用<Realm>包裹LockoutRealm,则查找只会考虑返回通用Realm的最外层CredentialHandler,而不是向下钻取到Realm 1}}包含您配置的CredentialHandler