2016-03-26 38 views
1

Java EE RESTアプリケーションに独自の認証と承認を追加しようとしています。私は、JAX-RSのSecurityContext,ContainerRequestFilter実装(JWTを使用)とエンドポイントメソッドの@RolesAllowed注釈を使用して作業バージョンを取得できました。しかし、私はEJBが必要であり、JAX-RSのSecurityContextを全く使用していません(ユーザーの役割に関係なくEJBAccessExceptionを取得しています)ので、別の解決策が必要です。EJB:カスタム認証と承認

実装可能なEJBにSecurityContextのようなものはありますか? Shiroのような図書館を使うべきですか?私はアプリケーション自体からユーザーを管理したいので、コンテナまたはLDAP提供のユーザー管理はオプションではありません。 JPAを使用してユーザーを認証して認証しています。

ので、主な質問は次のとおりです。

どのように私はJAX-RSのフィルタに基づいて、(@RolesAllowedアノテーションを使用して)するEJBで働く私自身の認証とロールベースの承認メカニズムを実装していますか?これらの役割を持つ具体的な認証済みユーザにリクエストが関連していることをEJBに伝えるにはどうすればよいですか?

もう1つ - 私はむしろベンダー固有のソリューションを避けたいと思いますが、もしあれば、私はJBoss/Wildflyに行きます。

+0

REST APIの横にEJBを公開しようとしていますか?そうでない場合は、ビジネスレイヤではなく、インターフェイスでAuthモジュールを使用してください。 –

+0

実際は - 私はそうではありません:)私はREST APIのみを使用します。そのため、認証はインターフェイスレイヤで実装できます。問題は、EJBとなるためにはRESTエンドポイントクラスが必要です。@RolesAllowedアノテーションは、JAX-RSではなくEJBによって処理されます。 –

答えて

1

私はしばらくの間これに取り組んできましたが、私自身の解決策で終わりました。これはのインターフェイスレベル(Pradeep Patiのように)で実装されています。したがって、豆にEJBでアクセスする必要がある場合、動作しません。私はhereを見つけたように

ContainerRequestFilter資源法(またはクラス)にアクセスすることができ、注釈、私が行うために必要なすべてがある:

1.自分@RolesAllowed注釈を実装します。

@Provider 
@Priority(Priorities.AUTHENTICATION) 
public class SecurityFilter implements ContainerRequestFilter { 

    @Context 
    private ResourceInfo resourceInfo; 

    @Override 
    public void filter(ContainerRequestContext context) throws IOException { 
     // here we have access to headers: 
     String authorizationHeader = context.getHeaderString("Authorization"); 

     // and, thanks to injected resourceInfo, to annotations: 
     RolesAllowed annotation = resourceInfo 
       .getResourceClass() // or getResourceMethod(), I've used both 
        .getAnnotation(RolesAllowed.class); 
     // and, finally, to the roles (after a null-check) 
     String[] roles = annotation.value(); 

     // then you can authenticate and authorize everything on your own using any method (I’ve used Basic Auth and JWT) 
     // and, if something fails, you can abort the request: 
     if (!isAuthenticated) { 
      context.abortWith(Response.status(Response.Status.UNAUTHORIZED).build()); 
     } else if (!isAuthorized) { 
      context.abortWith(Response.status(Response.Status.FORBIDDEN).build()); 
     }   
    } 
    ... 
} 
:カスタムの認証および承認と
@Inherited 
@Target({ElementType.TYPE, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface RolesAllowed { 
    String[] value(); 
} 

2.実装ContainerRequestFilter

しかし、私が評価されてきたAvishaiのソリューションすぎ(PicketLinkを使用します)。これは実装が少し難しく、複雑な場合もあります(たとえばJPAの基本シナリオでは約7-8 JPAのエンティティが必要です)。多くのオプションを持つ強固で拡張可能なセキュリティシステムが必要な場合は、より良い選択ですJPA、または同時に両方)、またはさまざまな認証オプション(たとえば、BasicとJWT authを同時に使用できますが、ヘッダーが異なる場合など)を使用します。話題にはおそらく何百もの賛否両論があるので、それは簡単な選択ではありません。

面白いことに、PicketLinkは、javax.annotationではなく、@org.picketlink.authorization.annotations.RolesAllowed注釈を使用しています。それでも、EJBコールでは、EJBインターセプタを使用し、ロールを確認するのにJAX-RSフィルタを使用しないため、正常に動作するはずです。

私にとっては、それは過度のように思えていたので、私は自分自身で、それほど洗練されていない(しかし働いている)解決策を思いついた。

1

現在のソリューションでPrincipalオブジェクトが正しく設定されていますか? EJBを含むJava EEセキュリティの中心です。

通常、JPAおよびカスタム認証方式をサポートするauth + IDMソリューションが必要です。 PicketLinkをお選びいただけます。残念ながら、ピケットリンクは現在、KeyCloakに取って代わられていると言われています。私は個人的には議論の余地があると考えています。 KeyCloakは、アプリケーション内IDMを提供しません。重要な機能であり、あなたが探しているものです。

JSR 375: Java™ EE Security APIは、上記のすべてをベンダーに中立な標準的な方法で解決する新しい仕様です。 SoteriaはJSR 375 RIです。現時点では、読み取り専用IDストアのみをサポートしています。

+0

はい、プリンシパルオブジェクトが正しく設定されました。問題はおそらくロールにのみ関連しています。 –

+0

PicketLinkについては、私はかなり単純な解決策に固執したいと思います.JAAをサポートするIDMとライブラリを混在させることは、私にとっては残酷なようです。プロジェクトは非常に小さいです。しかし、提案のおかげで、私はそれをチェックアウト:) –

1

私は、REST APIでHTTP認証ヘッダーを使用するとします。これは、コンテナの構成によって検証されます。これにはまだJava EEベンダーの中立仕様がないため、特定のベンダー固有の実装が存在します。ユーザーが検証されると、Principalが作成され、すべてのEJB @RolesAllowed注釈が機能します。

私はDukesForest to Wildflyを移植しました。その例を実際に見ることができます。残りのサービスのための公金を見て、web.xmlとjboss-web.xmlに注意してください。

基本的には、web.xmlのセキュリティ制約を定義します:また、データベース構成のためのエンティティのプロジェクトを見て

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>Secure payment service</web-resource-name> 
     <description/> 
     <url-pattern>/*</url-pattern> 
     <http-method-omission>GET</http-method-omission> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>USERS</role-name> 
    </auth-constraint> 
</security-constraint> 
<login-config> 
    <auth-method>BASIC</auth-method> 
</login-config> 
<security-role> 
    <role-name>USERS</role-name> 
</security-role> 

そしてWildflyがsecurity-domainは、データベースを照会する方法を指定する追加必要があります。

<security-domain name="dukes-forest" cache-type="default"> 
    <authentication> 
     <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"> 
      <module-option name="dsJndiName" value="java:jboss/ForestXADS"/> 
      <module-option name="rolesQuery" value="select NAME as 'ROLES', 'Roles' as 'ROLEGROUP' from forest.GROUPS g inner join forest.PERSON_GROUPS pg on g.ID = pg.GROUPS_ID join forest.PERSON p on p.EMAIL = pg.EMAIL where p.EMAIL = ?"/> 
      <module-option name="hashAlgorithm" value="MD5"/> 
      <module-option name="hashEncoding" value="HEX"/> 
      <module-option name="principalsQuery" value="select PASSWORD from forest.PERSON where EMAIL=?"/> 
     </login-module> 
    </authentication> 
    <authorization> 
     <policy-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"> 
      <module-option name="dsJndiName" value="java:jboss/ForestXADS"/> 
      <module-option name="rolesQuery" value="select NAME as 'ROLE', 'ROLES' as 'ROLEGROUP' from forest.GROUPS g inner join forest.PERSON_GROUPS pg on g.ID = pg.GROUPS_ID join forest.PERSON p on p.EMAIL = pg.EMAIL where p.EMAIL = ?"/> 
      <module-option name="hashAlgorithm" value="MD5"/> 
      <module-option name="hashEncoding" value="HEX"/> 
      <module-option name="principalsQuery" value="select PASSWORD from forest.PERSON where EMAIL=?"/> 
     </policy-module> 
    </authorization> 
</security-domain> 

これは基本的な考えです。

PS> Webフレームワークにセキュリティを実装するJava Security Quickstart Archetypeもあります。また、上記の例に基づいてHttp Basic認証を追加するのは簡単です。

0

私はあなたがテストフォルダに例を見ることができます

https://github.com/panchitoboy/shiro-jwt

のJava EEでの認証と認可をサポートするようにApache史郎上のライブラリのビルドを作りました。

大丈夫