現在、WSS4JとCXFを使用して作成しているWebサービスのセキュリティレイヤーに少し苦労しています。
プレーンテキストのパスワードをバックエンドに保存したくないのは明らかですが、ソルトハッシュのみを保持することを好みます。
ただし、サービス仕様は、クライアント(サービスを使用して一連のデータをプッシュする)によって、プレーンテキストのパスワード付きのUsernameTokensの使用にまで事前設定されています(すべての通信はSSL暗号化されます)。
今私が直面している問題は、私たちの側にあるリクエストセキュリティヘッダーからプレーンテキストのパスワードをハッシュし、ユーザー名とともにレコードと照合してリクエストを承認または拒否する方法を見つけることができないようです。
これまでに見つけたすべてのガイド、チュートリアル、またはサンプルプロジェクトは、入力インターセプターとして構成されたCallbackHandlerに依存しています。そのため、正しいプレーンテキストのパスワードを取得する必要があり、指定された資格情報と直接照合されます。ハッシュのみを保存する場合、オプションではありません。私が遭遇したいくつかのソースは、クライアントにハッシュを実行させるために単に推奨される同様の問題を解決しようとしていました。しかし、上で述べたように、これは私たちのケースでは不可能です。サービスの仕様は問題について明確であり、私たちの手には届きません。
この特に興味深いサウンドスレッドは残念ながら私にも役立ちませんでした: サーバーのパスワードがソルトおよびハッシュされているときにWSS UsernameTokenを実装する方法?
確かに、WSS4JInInterceptor/CallbackHandler以外の方法が必要です。これにより、受信したプレーンテキストのパスワードをダイジェストし、データベースのソルトハッシュと照合することができます。
どんなポインタでも本当にいただければ幸いです。ありがとう。
このヒントを提供してくれたCXFメーリングリストのIvan Brencsicsに感謝します。彼は書く:
私があなたの質問を正しく理解しているなら、あなたの問題はあなたが しない CallbackHandlerのパスワードにアクセスできないため、ハッシュしてデータベースと比較することはできません。
最近同じ問題に遭遇し、CallbackHandlerの代わりにorg.Apache.ws.security.validate.Validatorを登録することで解決しました。
たとえば:
<jaxws:endpoint ...>
<jaxws:properties>
<entry key="ws-security.ut.validator" value-ref="sqlTokenValidator"/>
</jaxws:properties>
</jaxws:endpoint>
...
<bean id="sqlTokenValidator" class="org.my.SqlTokenValidator"/>
そして最後にSqlTokenValidator:
public class SqlTokenValidator implements org.Apache.ws.security.validate.Validator {
@Override
public Credential validate(Credential credential, RequestData data)
throws WSSecurityException {
...
UsernameToken usernameToken = credential.getUsernametoken();
String username = usernameToken.getName();
String password = usernameToken.getPassword();
... hash the password
... sql_auth(username, hash password)
... if failed throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
return credential;
}
ああ、CXFメーリングリストをチェックするよう提案してくれたPolynomialに感謝します。それでも、適切なフォーラムを介したメーリングリストの魅力はよくわかりません;)