9

生のJavaランタイムで実行されているスタンドアロンEJBクライアントからJavaEEサーバーへのカスタムプリンシパルを使用したJAASサブジェクトの伝播をテストしています。JBossとWebSphereの両方の実装を対象としています。

このフォーラムスレッドによると、JBossで簡単に動作すると予想していました。

これが私のEJBクライアントコードコードスニペットです:

Subject subject = new Subject();
Principal myPrincipal = new MyPrincipal("me I myself");
subject.getPrincipals().add(myPrincipal);

PrivilegedExceptionAction<String> action = new PrivilegedExceptionAction<String>() {
    public String run() throws Exception {
            String result;
            System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext()));
            InitialContext ic = new InitialContext();
            Business1 b = (Business1) ic.lookup("StatelessBusiness1");
            result = b.getNewMessage("Hello World");
            return result;
        }
    };

result = subject.doAs(subject, action);
System.out.println("result "+result);

サーバー側のコードは次のとおりです。

public String getNewMessage(String msg) {
    System.out.println("getNewMessage principal: " + sessionContext.getCallerPrincipal());
    System.out.println("Current Subject: " + Subject.getSubject(AccessController.getContext()));
    return "getNewMessage: " + msg;
}

確かに、これがデフォルトの動作であっても、ejb-jar.xmlセッションBeanに次のセクションを追加しました。

<security-identity>
   <use-caller-identity/>
</security-identity>

私のセッションBeanはどのロールによっても保護されていません。

このIBMWebSphereインフォセンターのセクションによると、システムプロパティも有効にしましたcom.ibm.CSI.rmiOutboundPropagationEnabled=true

技術的に言えば、サービスコールはJBossまたはWebSphereのいずれかで適切に機能します。ただし、クライアントで作成されたカスタムプリンシパルを含むJAASサブジェクトは、サーバーに伝達されません。またはもちろん、SubjectJNDIコンテキストの作成とEJB呼び出しの直前にダンプされても問題ありません。

サーバーとクライアント(IBM Java6 SR9 FP2 ...)に対して同じJavaランタイムバージョンを実行します。MyPrincipalシリアル化可能なクラスはサーバーClassPath(AppServer/lib/extWebSphereの場合server/default/lib、JBossの場合)で使用できます。

WebSphereダンプ:

[8/31/12 11:56:26:514 CEST] 00000024 SystemOut     O getNewMessage principal: UNAUTHENTICATED
[8/31/12 11:56:26:515 CEST] 00000024 SystemOut     O Current Subject: null

JBossダンプ:

 12:30:20,540 INFO  [STDOUT] getNewMessage principal: anonymous
 12:30:20,540 INFO  [STDOUT] Current Subject: null

確かに、私はある種の魔法の呪文を逃しました。どれか知っていますか?

4

2 に答える 2

3

WASサーバーでセキュリティが有効になっていないと思われます。セキュリティが有効になっておらず、WASへの認証が行われていないため、資格情報はありません。したがって、への呼び出しgetCallerPrincipalはUNAUTHENTICATEDを返します。

WASでアプリケーションセキュリティをオンにする場合は、CSIv2プロトコルを介して認証する必要があります。スタンドアロンクライアントで独自のJAASサブジェクトを作成しても、それは実行されません。可能であれば、誰でも「ねえ、それは私です」というクレデンシャルを作成して、必要なリモートEJBにログインできます。

実行中の実行スレッドにサブジェクトをアタッチすることで、コードはサーバー上で機能します。サブジェクト/クレデンシャルをネットワーク上で流すには、サブジェクト情報のシリアル化を実行し、クレデンシャルでIDを主張する当事者の信頼を確保するためのプロトコルが必要です。スタンドアロンクライアントから、WASは基本認証、LTPA、およびKerberosの形式でユーザー情報を受け入れます。これは、管理コンソール内のインバウンドCSIv2構成で構成できます。これは、前に参照した情報センターのリンクに記載されています。

それは楽しいものです。幸運を。

于 2012-09-12T04:15:04.770 に答える
0

おそらくこれは、プロプライエタリなWebsphereクラスを使用するための価格に役立ちます。私が覚えているように、websphereはjaas caller-subjectを伝播しません、これはibmに典型的です

    package foo.bar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import javax.security.auth.login.CredentialExpiredException;
import org.apache.log4j.Logger;
import com.ibm.websphere.security.WSSecurityException;
import com.ibm.websphere.security.auth.CredentialDestroyedException;
import com.ibm.websphere.security.auth.WSSubject;
import com.ibm.websphere.security.cred.WSCredential;

public class IdentityHelper
{
    private static final Logger log = Logger.getLogger(IdentityHelper.class);
    private static final String CLASS_OBJECT = "java.util.HashMap";
    private static final String KEY_OBJECT = "java.lang.String";
    private static final String VALUE_OBJECT = "java.util.HashSet"; 

    private Subject subject=null;
    private WSCredential creds;
    private Set publicCredentials=null;
    public IdentityHelper(Subject _subject) throws WSSecurityException
    {
        if(_subject==null)
        {
            IdentityHelper.log.warn("given subject was null, using Caller-Subject or the RunAs-Subject!");
            this.subject = WSSubject.getCallerSubject();
            if(this.subject==null)this.subject=WSSubject.getRunAsSubject();
        }
        else
        {           
            this.subject=_subject;
        }
        init();
    }
    public IdentityHelper() throws WSSecurityException
    {
        this.subject=WSSubject.getRunAsSubject();
        if(this.subject==null)
        {
            IdentityHelper.log.warn("using Caller-Subject NOT the RunAs-Subject!");
            this.subject = WSSubject.getCallerSubject();
        }
        init();
    }

    private void init() throws WSSecurityException
    {
        Set<WSCredential> credSet= this.subject.getPublicCredentials(WSCredential.class);
        //set should contain exactly one WSCredential
        if(credSet.size() > 1) throw new WSSecurityException("Expected one WSCredential, found " + credSet.size());
        if(credSet.isEmpty())
        {
            throw new WSSecurityException("Found no credentials");
        }
        Iterator<WSCredential> iter= credSet.iterator();
        this.creds=(WSCredential) iter.next();
        this.publicCredentials=this.subject.getPublicCredentials();
    }
    public WSCredential getWSCredential() throws WSSecurityException
    {
        return this.creds;
    }
    public List<String> getGroups() throws WSSecurityException,CredentialDestroyedException,CredentialExpiredException
    {
        WSCredential c = this.getWSCredential();
        return c.getGroupIds();
    }
    /**
     * helper method for obtaining user attributes from Subject objects.
     * @param subject
     * @return
     */
    @SuppressWarnings("unchecked")
    public Map<String, Set<String>> getAttributes()
    {
        Map<String, Set<String>> attributes = null;
        Iterator<?> i = this.subject.getPublicCredentials().iterator();
        while (attributes == null && i.hasNext())
        {
            Map<String, Set<String>> tmp = null;
            Object o = i.next();
            if(IdentityHelper.log.isDebugEnabled())
            {
                IdentityHelper.log.debug("checking for attributes (class name): " + o.getClass().getName());
            }
            if(!o.getClass().getName().equals(CLASS_OBJECT))
                continue;//loop through
            tmp = (Map) o;
            Object tObject = null;
            Iterator<?> t = null;
            t = tmp.keySet().iterator();
            tObject = t.next();
            if(IdentityHelper.log.isDebugEnabled())
            {
                IdentityHelper.log.debug("checking for attributes (key object name): " + tObject.getClass().getName()); 
            }
            if(!tObject.getClass().getName().equals(KEY_OBJECT))
                continue;//loop through
            t = tmp.values().iterator();
            tObject = t.next();
            if(IdentityHelper.log.isDebugEnabled())
            {
                IdentityHelper.log.debug("checking for attributes (value object name): " + tObject.getClass().getName()); 
            }
            if(!tObject.getClass().getName().equals(VALUE_OBJECT))
                continue;//loop through
            attributes = (Map) o;
        }
        if (attributes == null)
        {
            attributes = new HashMap<String, Set<String>>(); 
        }
        return attributes;
    }
    public Subject getSubject()
    {
        return this.subject;
    }
    protected Set getPublicCredentials() {
        return publicCredentials;
    }


}

参照:JAASのスレッドからの呼び出し元サブジェクトの取得およびスレッドからのRunAsサブジェクトの取得

于 2013-04-26T14:27:23.840 に答える