2012-03-19 12 views
1

私は、SSLによる基本認証を使用するJavaサービスを作成しようとしています。 SSLの設定は非常に簡単でしたが、認証を設定することははるかに問題でした。次のように私のサーバーがGlassfishの3.の機能上のJavaEEを使用しているGlassfishでjax-wsで認証できません

Exception in thread "AWT-EventQueue-0" javax.xml.ws.soap.SOAPFaultException: javax.ejb.EJBAccessException 
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:178) 
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:111) 
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:108) 
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:78) 
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:129) 
at $Proxy30.reverseString(Unknown Source) 
at securitytestclient.SecurityTestClient.reverseStringSOAP(SecurityTestClient.java:305) 
at securitytestclient.SecurityTestClient.buttonReverseActionPerformed(SecurityTestClient.java:217) 
at securitytestclient.SecurityTestClient.access$000(SecurityTestClient.java:20) 
at securitytestclient.SecurityTestClient$1.actionPerformed(SecurityTestClient.java:72) 
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018) 
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341) 
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) 
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) 
at javax.swing.plaf.basic.BasicButtonListener$Actions.actionPerformed(BasicButtonListener.java:303) 
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1661) 
at javax.swing.JComponent.processKeyBinding(JComponent.java:2879) 
at javax.swing.JComponent.processKeyBindings(JComponent.java:2926) 
at javax.swing.JComponent.processKeyEvent(JComponent.java:2842) 
at java.awt.Component.processEvent(Component.java:6282) 
at java.awt.Container.processEvent(Container.java:2229) 
at java.awt.Component.dispatchEventImpl(Component.java:4861) 
at java.awt.Container.dispatchEventImpl(Container.java:2287) 
at java.awt.Component.dispatchEvent(Component.java:4687) 
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1890) 
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:752) 
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1017) 
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:889) 
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:717) 
at java.awt.Component.dispatchEventImpl(Component.java:4731) 
at java.awt.Container.dispatchEventImpl(Container.java:2287) 
at java.awt.Window.dispatchEventImpl(Window.java:2713) 
at java.awt.Component.dispatchEvent(Component.java:4687) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707) 
at java.awt.EventQueue.access$000(EventQueue.java:101) 
at java.awt.EventQueue$3.run(EventQueue.java:666) 
at java.awt.EventQueue$3.run(EventQueue.java:664) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
at java.awt.EventQueue$4.run(EventQueue.java:680) 
at java.awt.EventQueue$4.run(EventQueue.java:678) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) 

私は次の例外を受け取り@RolesAllowedアノテーションでマークされたメソッドを呼び出そうといつでも...豆で定義されています...

package com.intproimp.testing.beans; 

import javax.annotation.security.PermitAll; 
import javax.annotation.security.RolesAllowed; 
import javax.ejb.Local; 
import javax.ejb.Stateless; 

@Stateless(mappedName="ejb/StringOps/Bean") 
@Local(StringOps.class) 
public class StringOpsBean implements StringOps { 

    @PermitAll 
    @Override 
    public String echoString(String str) { 
     return str; 
    } 

    @RolesAllowed({"admin"}) 
    @Override 
    public String reverseString(String str) { 
     char[] input = str.toCharArray(); 
     char[] output = new char[input.length]; 
     for (int i = 0; i < output.length; i++) { 
      output[i] = input[input.length - i - 1]; 
     } 
     return new String(output); 
    } 
} 

私は、セキュリティレルムは、1人のユーザー(名前の単なるファイルレルムです...私のweb.xmlファイルに

<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>testing-frealm</realm-name> 
</login-config> 
<security-role> 
    <description/> 
    <role-name>admin</role-name> 
</security-role> 
<security-role> 
    <description/> 
    <role-name>user</role-name> 
</security-role> 

をログインの設定を追加しました:「アンドリュー」、パス: " 12345 ")。 は私がまた私のglassfish-web.xmlにクライアント側で

<security-role-mapping> 
    <role-name>user</role-name> 
    <group-name>user</group-name> 
</security-role-mapping> 
<security-role-mapping> 
    <role-name>admin</role-name> 
    <group-name>admin</group-name> 
</security-role-mapping> 

を役割グループのマッピングを追加しました、私はからテストする簡単なSwingアプリケーションを持っている...

Swing Test Application

呼び出しはSOAPチャネルの逆関数に行われます。 SOAPクライアントコンポーネントは、New-> WebService Client関数を介してNetBeansで生成されます。そして、リバースボタンクリックに関連付けられたアクションは、私が欠けているだけでいくつかの小さなものがあると確信しているが、私は日、まだ避難所のために問題を見てきた

private void addAuthenticateionSOAP(StringOpsSOAP port) { 
    ((BindingProvider) port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, fieldUsername.getText()); 
    ((BindingProvider) port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, fieldPassword.getText()); 
} 

private String reverseStringSOAP(String str) { 
    StringOpsSOAP_Service service = new StringOpsSOAP_Service(); 
    StringOpsSOAP port = service.getStringOpsSOAPPort(); 
    if (checkAuthentication.isSelected()) addAuthenticateionSOAP(port); 
    return port.reverseString(str); 
} 

...ですそれを見つけました。

- 私はWebServiceコードを投稿していないので、混乱が生じるかもしれないことに気付きました。文字列関数が含まれているEJBは、SOAP WebServiceの豆を介してアクセスされ...

package com.intproimp.test.web; 

import com.intproimp.test.beans.StringOps; 
import javax.ejb.EJB; 
import javax.jws.WebService; 
import javax.ejb.Stateless; 
import javax.jws.WebMethod; 
import javax.jws.WebParam; 

@WebService(serviceName = "StringOpsSOAP") 
@Stateless() 
public class StringOpsSOAP { 

    @EJB 
    private StringOps ops; 

    @WebMethod(operationName = "echoString") 
    public String echoString(@WebParam(name = "str") String str) { 
     return ops.echoString(str); 
    } 

    @WebMethod(operationName = "reverseString") 
    public String reverseString(@WebParam(name = "str") String str) { 
     return ops.reverseString(str); 
    } 
} 
+0

おそらくGlassfishはいくつかの魔法を使っていますが、あなたはサービスとEJBを公開しましたが、それをSOAP WSと呼びます。 JSR-181アノテーション([example](https://community.jboss.org/wiki/JBWS181HelloWorld)を参照)を使用してリモートEJBとして呼び出すか(EJBワールド内の認証ゲームに従う)、またはWSを公開するか、実装クラスの '@WebService'とSOAPとして公開したい各メソッドのそれぞれのメソッドの' @WebMethod'です。 P.S.あなたが持っている 'EJBAccessException'を調べることに興味があります。 –

+0

私は、EJBがWebサービスの注釈付きクラスによって使用されることを明確にする必要があります。質問を編集してコードを追加します。 –

+0

この問題を解決できましたか? – TPete

答えて

2

あなたは、特定のURLへのアクセスを許可するユーザーを説明し、あなたのweb.xml<security-constraint>を追加する必要があります。これはSecuring Web ApplicationsJava EE 6チュートリアルに記載されています。

<security-constraint> 
<display-name>WebServiceSecurity</display-name> 

<web-resource-collection> 
    <web-resource-name>Authorized users only</web-resource-name> 
    <url-pattern>/yoururl</url-pattern> 
    <http-method>POST</http-method> 
</web-resource-collection> 

<auth-constraint>  
    <role-name>user</role-name> 
    <role-name>admin</role-name> 
</auth-constraint> 

編集:あなたのケースでは、このようなものである必要がありますが、クラスや出版に@webservice注釈を追加することによって、あなたのステートレスセッションBeanのWebサービスを作る持っている場合、これはトリックを行う必要がありますdma_kとして@webmethodを使用する方法は、コメントで述べた。

編集2: 上記のリンクから:

の指定セキュリティ制約

セキュリティ制約が彼らのURLマッピングを使用したリソースの集合へのアクセス権限を定義するために使用されます。上さらに

:ウェブリソースコレクション

のurl-patternを指定

は、URIを保護するための要求をリストするために使用されます。多くのアプリケーションは、保護されていないリソースと保護されたリソースの両方を持っています。 リソースに無制限のアクセスを提供するには、その特定の要求URIにセキュリティ制約を設定しないでください。

そして:認可の制約

認可制約を指定

は、認証や名前、このセキュリティによって宣言されたURLパターンおよびHTTPメソッドにアクセスする権限ロールの要件を確立します制約。 許可制約がない場合、コンテナはユーザー認証を要求せずに要求を受け入れる必要があります。

いいえ、<security-constraint> => no authentication => no roles available。

使用の監査またはこれを確認するために、WebServiceContextから(getUserPrincipal()isUserInRole())の情報をお読みください。

+0

StringOpsBean.reverseString(String)にある@RolesAllowedアノテーションは、そのメソッド呼び出しへのアクセスを効果的にブロックします。問題は、Glassfishがユーザーログインを受け付けていないように見えることです。 –

+1

@AndrewRademacherそのメソッドへのアクセスを制限する必要があります。これを行うには、セキュリティ制約を指定する必要があります。それがなければ、認証は必要ありません。認証がなければ、ユーザーの役割はなく、そのためユーザーにはそのメソッドへのアクセス権が与えられません。 BTW:監査を有効にすることは、セキュリティを設定する際に本当に助けになりました。 – TPete

+0

したがって、/ *のパスを持つ制約を追加した場合、それはuserでした。 @RolesAllowed({"admin"})はそれの上にスタックするでしょうか? reverseStringを呼び出すには、ユーザーと管理者の両方になる必要がありますか? –

関連する問題