3

WS-security で保護された SOAP サービス (Java) を 1 つ 1 つ終了します。もう一方の端は、SOAP サーバーのクライアントとして機能する HTTP サーバー (Java) です。

次の委任チェーンを持つユーザーにシングル サインオン (Negotiate/Kerberos を使用) を実装したいと考えています: ブラウザ >> HTTP サーバー >> SOAP サーバー

ブラウザ >> HTTP サーバーは問題なく動作しています (HTTP でネゴシエート)。

HTTP サーバーでユーザーになりすます、2 番目のホップ HTTP サーバー >> SOAP サーバーは、JNA を使用したいのでより困難であり、1 つのトークンを使用して認証を実行したい (ハンドシェークを回避する)。一方向認証しか必要ないため、可能であると思われます。

エンベロープで HTTP サーバーから SOAP サーバーにトークンを渡すことも機能しており、SOAP サーバー側にインターセプターがあります。私の唯一の問題は、AcceptSecurityContext を呼び出すときにSEC_I_CONTINUE_NEEDEDステータスにならない興味深いトークンを生成することです。

SOAP サービスのトークンを取得するクライアント コード (JNA は Waffle プロジェクトによってラップされます):

import sun.misc.BASE64Encoder;
import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsSecurityContextImpl;

public class WindowsAuthenticator {

public static final String securityPackage = "Negotiate";

public static String getKrbToken(String targetSPN) {
    if (null == targetSPN || targetSPN.trim().isEmpty()) {
        return null;
    }
    IWindowsSecurityContext ctx = WindowsSecurityContextImpl.getCurrent(securityPackage, targetSPN);
    byte[] token = ctx.getToken();
    return new BASE64Encoder().encode(token);
}

private WindowsAuthenticator() {
    super();
}

}

Kerberos トークンを検証するための SOAP サーバー コード

import org.apache.log4j.Logger;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.message.token.BinarySecurity;
import org.apache.ws.security.validate.Credential;
import org.apache.ws.security.validate.Validator;
import waffle.windows.auth.IWindowsAuthProvider;
import waffle.windows.auth.IWindowsIdentity;
import waffle.windows.auth.IWindowsSecurityContext;
import waffle.windows.auth.impl.WindowsAuthProviderImpl;

public class KerberosTokenValidator implements Validator {

private static final Logger logger =      Logger.getLogger(KerberosTokenValidator.class);
private final IWindowsAuthProvider windowsAuthProvider;

public KerberosTokenValidator() {
    this.windowsAuthProvider = new WindowsAuthProviderImpl();
}

@Override
public Credential validate(Credential credential, RequestData data) throws     WSSecurityException {
    BinarySecurity token = credential.getBinarySecurityToken();
    byte[] binaryToken = token.getToken();
    String id = token.getID();
    String type = token.getValueType();
    final IWindowsSecurityContext securityContext;
    try {
        securityContext = this.windowsAuthProvider.acceptSecurityToken(id, binaryToken, "Negotiate");


        this.windowsAuthProvider.acceptSecurityToken(id, binaryToken, "Negotiate");

        final IWindowsIdentity windowsIdentity = securityContext.getIdentity();
        securityContext.dispose();

    } catch (Exception exception) {
        logger.warn("error logging in user: " + exception.getMessage());
        throw new WSSecurityException("Could not auth....");
    }

    return null;
}

}

問題は、acceptSecurityTokenがSEC_I_CONTINUE_NEEDEDを返し、(最初のホップで HTTP を介して行われたように) ハンドシェイクを行うことになります。ここでは、(可能であれば) サーバーが単一のトークンで満足することを本当に望んでいます (SOAP API の現在の設計は完全にステートレスであり、この方法で維持することが望まれます)。

4

0 に答える 0