0

WebアプリのSSOソリューションにWaffleを使用しています。

すべて正常に動作しますが、一部の機能を少し変更したいと思います。

現在、ユーザーがドメインに接続していない場合、SSOは失敗し、小さな認証ダイアログが開きます。

ここに画像の説明を入力してください

Windows認証には、次のような形式のユーザー名が必要ですDomain\Usernameが、ほとんどのユーザーは、ユーザー名の前にドメインを追加することを知りません。そのため、指定されていない場合はデフォルトのドメイン名を提供したいと思います。

デコードされた認証トークンにアクセスできるようにするオーバーライド可能なワッフル関数を見つけました。ワッフル関数にを追加するprintlnと、ユーザー名がプレーンテキストで表示されます(ダイアログに入力された内容に応じて、ドメインの有無にかかわらず) )::

public IWindowsSecurityContext acceptSecurityToken(String connectionId, byte[] token, String securityPackage) {

    // I can see the passed username in the logs with this
    System.out.println(new String(token));

    // I don't understand any of the JNA stuff below this comment:
    IWindowsCredentialsHandle serverCredential = new WindowsCredentialsHandleImpl(
            null, Sspi.SECPKG_CRED_INBOUND, securityPackage);
    serverCredential.initialize();

    SecBufferDesc pbServerToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE);
    SecBufferDesc pbClientToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, token);

    NativeLongByReference pfClientContextAttr = new NativeLongByReference();

    CtxtHandle continueContext = _continueContexts.get(connectionId);

    CtxtHandle phNewServerContext = new CtxtHandle();
    int rc = Secur32.INSTANCE.AcceptSecurityContext(serverCredential.getHandle(), 
            continueContext, pbClientToken, new NativeLong(Sspi.ISC_REQ_CONNECTION), 
            new NativeLong(Sspi.SECURITY_NATIVE_DREP), phNewServerContext, 
            pbServerToken, pfClientContextAttr, null);

    WindowsSecurityContextImpl sc = new WindowsSecurityContextImpl();
    sc.setCredentialsHandle(serverCredential.getHandle());
    sc.setSecurityPackage(securityPackage);
    sc.setSecurityContext(phNewServerContext);

    switch (rc)
    {
        case W32Errors.SEC_E_OK:
            // the security context received from the client was accepted
            _continueContexts.remove(connectionId);
            //  if an output token was generated by the function, it must be sent to the client process
            if (pbServerToken != null 
                    && pbServerToken.pBuffers != null
                    && pbServerToken.cBuffers.intValue() == 1 
                    && pbServerToken.pBuffers[0].cbBuffer.intValue() > 0) {
                sc.setToken(pbServerToken.getBytes());
            }
            sc.setContinue(false);
            break;
        case W32Errors.SEC_I_CONTINUE_NEEDED:
            // the server must send the output token to the client and wait for a returned token
            _continueContexts.put(connectionId, phNewServerContext);
            sc.setToken(pbServerToken.getBytes());
            sc.setContinue(true);
            break;
        default:
            sc.dispose();
            WindowsSecurityContextImpl.dispose(continueContext);
            _continueContexts.remove(connectionId);
            throw new Win32Exception(rc);
    }

    return sc;
}

その関数全体はWaffleAPIからのものであり、最初にprintlnを追加しただけです。

渡されたユーザー名は、このトークン内のランダムなバイト文字の束の間にプレーンテキストで出力されます(ÉsR=ÍtÍö?æ¸+Û-)。

私は確かにJNAとJava全般に頭を悩ませていますが、ここでユーザー名を確認できるので、このトークンのユーザー名部分にドメイン名を追加する方法があるはずだと思いました。私は間違っている可能性があります。

pbClientToken私の他のアイデアは、このメソッドが渡される生のbyte[]トークンから作成されたドメインを追加することでした。

これpbClientTokenJNAStructureオブジェクトの派生物です。有望に見えたStucture方法writeFieldですが、どの分野を書けばいいのかわからないようです。メソッドはStructure.getFieldsから利用できないようですpbClientToken

これがbyte[]処理またはJNAに精通している人にとっては単純な問題であることを望んでいました。

4

1 に答える 1

1

これはできません。このダイアログの背後で行われるのは、ユーザーのマシン上のLogonUserの呼び出しです。これにより、チケットが提供され、サーバーに送信されます。残念ながら、サーバーは同じドメインに属していないため、ユーザー名を抽出できたとしても、まったく役に立ちません。

于 2013-02-21T05:25:37.730 に答える