2

デプロイメント記述子の代わりにアノテーションを使用してGlassfish3にデプロイされるアプリケーションを保護しようとしています。しかし、私はそれを正しく動作させることができませんでした。サービスにアクセスしようとすると、サーバーエラー500が発生し、次のメッセージが表示されます。

type Exception report

message

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.ejb.AccessLocalException: Client not authorized for this invocation
root cause

javax.ejb.AccessLocalException: Client not authorized for this invocation

EJBは次のようになります。

@Path("/myresource")
@Stateless
@RolesAllowed("user-role")
public class MyResource {

    @GET
    @Path("/{uuid}")
    public Response getData(@PathParam("uuid") final String uuid) {
            ....
    }
}

sun-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD GlassFish Application Server 3.0 Servlet 3.0//EN" 
"http://www.sun.com/software/appserver/dtds/sun-web-app_3_0-0.dtd">
<sun-web-app>
    <security-role-mapping>
        <role-name>user-role</role-name>
        <group-name>user-group</group-name>
    </security-role-mapping>
</sun-web-app>

これはweb.xmlです:

<web-app id="myservice" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>org.test.myservice</display-name>

    <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>org.test.myservice.rest</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>file</realm-name>
    </login-config>

    <security-role>
        <role-name>user-role</role-name>
    </security-role>
</web-app>

glassfishのファイルレルムは、sun-web.xmlで指定されたユーザーとロールを使用して設定され、デプロイメント記述子を介してアプリケーションのセキュリティを設定するときに正常に機能しています。

このドキュメントを正しく理解していれば、名前が同じであればセキュリティロール参照をリンクする必要はありません。http://docs.oracle.com/javaee/5/tutorial/doc/bnbyl.html#bnbyt 私が見逃しているアイデアはありますか?

編集 必要な情報をアノテーションで指定できないという問題に関連して、別の問題があり、この問題について考えさせられました。たぶん、それは最初の質問をもう少し明確にするでしょう:上記の例では、リソース/ myresource/*はロール'user-role'を持つユーザーのみが利用できます。ただし、パス/ myresource / * / thumbnail(/ myresource / [uuid] / thumbnailに変換)に認証なしで使用できる2番目のリソースがある場合、これはurl-mappingでsecurity-constraintsを指定することによっては不可能です。定数の間にワイルドカードを使用することはできないようです。ただし、これは、注釈によってメソッドにアクセスできるロールを指定することで実行できます。上記のように、私はそうすることができませんでした。そのようなマッピングはどのように行うことができますか?

4

2 に答える 2

2

特定のリソースとパスをブロックし、許可制約を指定するには、web.xml記述子のsecurity-constraint要素を使用する必要があります。

これは、 OracleのJava EE 6チュートリアルで説明されているように、ProgrammaticSecurityを使用してよりきめ細かいコントロールを追加できないことを意味するものではありません。

プログラムによるセキュリティはアプリケーションに組み込まれており、セキュリティの決定を行うために使用されます。プログラムによるセキュリティは、アプリケーションのセキュリティモデルを表現するには、宣言型のセキュリティだけでは不十分な場合に役立ちます。


編集した質問に従って。

この要素を使用して、security-constraint登録されていないすべてのユーザーへのアクセスをブロックします。これにより、全員が認証を強制されるため、アプリケーションは自分の役割を認識できます。次に、プログラムによるセキュリティを使用して、さまざまなリソースへのアクセスをきめ細かく制御できます。

基本認証では、他に方法はないと思います。基本ユーザーの認証を避けたい場合は、フォーム認証を使用して、プログラムで認証をバックグラウンドで処理し、ユーザーが認識していない場合でも、HttpServletRequest#login()を使用して認証を行う必要があります。

どちらの方法でも、説明した方法で権限を設定できるはずです。不正な例外をよりスムーズに処理したい場合は、@RolesAllowedアノテーションを削除して、代わりに次のようなものを使用することをお勧めします。

@GET
@Path("/{uuid}")
public Response getData(@PathParam("uuid") final String uuid, @Context SecurityContext sc) {
    if (sc.isUserInRole("MyRole")) {
        return result;
    } else {
        return notAllowedResult;
    }
}
于 2012-12-03T13:29:43.547 に答える
2

Roles-AllowedはEJB構造であり、セキュリティ制約によって処理されるリソースへのアクセスと一致しません。

残念ながら、2つのセキュリティの概念は適切にメッシュ化されておらず、許可されていない場合は401を取得する代わりに(Webの概念)、受信しているセキュリティの例外(およびEJBの概念)を取得します。実際、EJB WebサービスにRolesAllowedで注釈を付け、無効な役割でWebサービスにアクセスしようとすると、どのようなエラーが発生するかわかりません。その場合、SOAP障害が発生すると思います。

EJBセキュリティは、許可されていない人を締め出すシステムですが、これは最後の努力です。メソッド呼び出しにユーザーをルーティングする決定は、すでに事前に行われていることを前提としています。たとえば、メソッドが許可されているかどうかをテストする高レベルの方法はありません。むしろ、メソッドを呼び出して例外をキャッチすることしかできません。

したがって、厳しい真実は粗雑なゲートキーパーを超えているので、プログラマティックセキュリティを活用したいと考えています。

于 2012-12-03T14:42:13.100 に答える