- PR -

SSL認証におけるロール名について

1
投稿者投稿内容
だっちょ
大ベテラン
会議室デビュー日: 2006/12/05
投稿数: 115
投稿日時: 2007-05-08 13:22
 GlassFishで
http://blogs.sun.com/xiaojun/
のようにSSLで双方向認証を行い、WEBアプリケーションでロールを取得しようと思ったのですが、適当なPrincipalが設定されてないので、そこから呼び出すEJBのSessionContextのgetCallerPrincipalがANONYMOUSになってしまい、足りない設定がわからず困っています。

 スマートカードで(PIN入力して)SSL認証した直後のJSPページで
request.getAttribute("javax.servlet.request.X509Certificate")
を見ると正しい証明書があるのですが、
Subject.getSubject(AccessController.getContext())
でSubjectを見るとnullとなってしまいます。
(trustStoreにはカードのルート証明書をいれている)
web.xmlは以下のようにauth-constraintを設定してません。(accessが拒否されるので。)
コード:
--- web.xml ---
    <security-constraint>
      <web-resource-collection>
        <web-resource-name>Protected Area</web-resource-name>
        <url-pattern>/*</url-pattern>
	<http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
	<http-method>PUT</http-method>
      </web-resource-collection>

      <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
    </security-constraint>

    <login-config>
      <auth-method>CLIENT-CERT</auth-method>
<realm-name>certificate</realm-name>
    </login-config>

    <security-role>
       <role-name>一般ユーザ</role-name>
    </security-role>
    <security-role>
       <role-name>GENERAL</role-name>
    </security-role>


--- sun-application.xml(sun-web.xmlで指定しても同じ) ---
  <security-role-mapping>
    <role-name>GENERAL</role-name>
    <principal-name>(カード証明書のSubject名)</principal-name>
  </security-role-mapping>
----------------------



 認証された証明書が取れるので、強制的にSubjectを作って、メソッドfuncを呼び出すときに
Subject.doAs(subject, new PrivilegedExceptionAction() {
public Object run() throws Exception {
func(m_params);
return(null);
}
});
とでもすれば、@RolesAllowedなメソッドも呼び出せると思うのですが、
何か基本的な設定が足りないのでしょうか?
 全部の関数にこれを行うのは面倒なので、@RunAsを使えば
よいのかと思って、クラスやメソッドに指定してみましたが、nullのままのようです。
これも何か使い方が間違っているのでしょうか?
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-05-08 14:13
GlassfishでSSLクライアント認証を試した事がなく、
正確なJavaEE仕様での定義も知らないので参考までに。

引用:

web.xmlは以下のようにauth-constraintを設定してません。(accessが拒否されるので。)


Webコンテナはauth-constraintで制約がかかっていないと
認証自体してくれないようなので必須なんだと思います。

引用:

 認証された証明書が取れるので、強制的にSubjectを作って、メソッドfuncを呼び出すときに
Subject.doAs(subject, new PrivilegedExceptionAction() {
public Object run() throws Exception {
func(m_params);
return(null);
}
});
とでもすれば、@RolesAllowedなメソッドも呼び出せると思うのですが、
何か基本的な設定が足りないのでしょうか?


こういう使い方はできないようです。
アプリケーションが勝手に認証した主体の権限で実行されたら
コンテナ管理のセキュリティも何もないからなのでしょう。

Webコンテナが管理する認証機構を経由して認証された場合のみ、
EJB等のコンテキストにも自動的に伝搬されるようです。
だっちょ
大ベテラン
会議室デビュー日: 2006/12/05
投稿数: 115
投稿日時: 2007-05-08 15:12
 ありがとうございます。
しかし、状況は以下のようになります。

1) auth-constraintがなくてもスマートカードが挿入されてなければ、
「スマートカードを挿入してください」とダイアログが出て、
キャンセルを選択する(つまりユーザ証明書を提示しない)と、
「ページを表示できません」とエラーになります。
また対象になる証明書が複数入っていた場合には、証明書を選択させています。
このため、ちゃんと認証していると考えています。

2) 呼び出しているEJBのメソッドを1つだけ
@RolesAllowed({"GENERAL"})
にして、他はすべて
@PermitAll
にした場合、そのメソッドを呼び出す画面で
javax.ejb.EJBException: nested exception is: java.rmi.AccessException: CORBA NO_PERMISSION 9998 Maybe; nested exception is:
org.omg.CORBA.NO_PERMISSION: vmcid: 0x2000 minor code: 1806 completed: Maybe
java.rmi.AccessException: CORBA NO_PERMISSION 9998 Maybe; nested exception is:
org.omg.CORBA.NO_PERMISSION: vmcid: 0x2000 minor code: 1806 completed: Maybe
at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.mapSystemException(Util.java:222)
at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.wrapException(Util.java:678)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:210)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:119)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:197)
となりました。このまま、呼び出すWEBアプリのBEANの方を
コード:
    public String getName()
    {
        return(m_sys.getName());
    }


から
コード:
    public String getName()
    {
        Principal pr = new RolePrincipal("GENERAL");
        Set<Principal> prs = new HashSet<Principal>();
        prs.add(pr);
        Set pub = new HashSet();
        Set priv = new HashSet();
        Subject sub = new Subject(true, prs, pub, priv);
        m_role = null;
        Subject.doAs(sub, new PrivilegedAction() { 
            public Object run()  { 
                try {
                    m_role = getNameIn(); 
                }
                catch (Exception e) {
                }
                return(null); 
            }
        });
        return(m_role);
    }
    private final String getNameIn()
    {
        return(m_sys.getName());
    }


に変更するとエラーがおきずにメソッドが正常に進むようになりました。


あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-05-08 15:29
適当に作ったSubjectにdoAs()できているって事ですよね。
これってセキュリティ的に問題ないんでしょうか・・・。
うーん。。

以前にTomcatでFORM認証を行おうとした場合は、
ロールを必要とする制約にひっかかるようにしないと、
認証ページを出してくれなかったので先ほどのように書きました。

とりあえず、私にわかる範囲では、
Glassfishの側でRoleにマッピングするのが正解なようです。
http://blogs.sun.com/xiaojun/date/200606

このサイトではsun-web.xmlでマッピングしていますが、
Realmの方でもマッピングできそうな気もします。
だっちょ
大ベテラン
会議室デビュー日: 2006/12/05
投稿数: 115
投稿日時: 2007-05-08 15:44
 失礼しました.
 2)のソースでは例外を全部catchしているため、そのまま通っていただけで、同じ例外が発生していました。
 たぶんdoAsできる権限を設定すれば動くようになるのでしょうが、やはりSSL認証中にロールを設定するようにできる必要がありそうです。
1

スキルアップ/キャリアアップ(JOB@IT)