2014-01-09 10 views
6

RESTEasyをGuiceで使用してREST APIを開発していますが、Dropwizardにある@Authと同様のアノテーションを使用して基本認証を組み込もうとしています。GuiceのRESTEasyのリソースメソッドにプリンシパルを挿入

@Path("hello") 
public class HelloResource { 
    @GET 
    @Produces("application/json") 
    public String hello(@Auth final Principal principal) { 
     return principal.getUsername(); 
    } 
} 

とハローリソースの起動は許可HTTPリクエストヘッダおよび方法主要パラメーターにプリンシパルを注入成功に渡される資格情報を使用して、基本的な認証を行ういくつかのコードによってインターセプトされなければなりません。アノテーションに許可されたロールのリストを渡すこともできます。 @Auth("admin")

私は本当にこれを達成するためにどの方向にいくつかのアドバイスが必要ですか?

答えて

7

あなたの最善の策はリクエストスコープ内で中間値を使用することだと思います。 HelloResourceをシングルトンスコープに入れないと仮定すると、この中間値をいくつかのContainerRequestFilter実装とリソースに注入することができます。このContainerRequestFilter実装の中に必要なすべての認証情報と認証情報を埋め込むことができます。

それは次のようなものになります。

// Authentication filter contains code which performs authentication 
// and possibly authorization based on the request 
@Provider 
public class AuthFilter implements ContainerRequestFilter { 
    private final AuthInfo authInfo; 

    @Inject 
    AuthFilter(AuthInfo authInfo) { 
     this.authInfo = authInfo; 
    } 

    @Override 
    public void filter(ContainerRequestContext requestContext) throws IOException { 
     // You can check request contents here and even abort the request completely 
     // Fill authInfo with the data you need 
     Principal principal = ...; // Ask some other service possibly 
     authInfo.setPrincipal(principal); 
    } 
} 

@Path("hello") 
public class HelloResource { 
    private final AuthInfo authInfo; 

    @Inject 
    HelloResource(AuthInfo authInfo) { 
     this.authInfo = authInfo; 
    } 

    @GET 
    @Produces("application/json") 
    public String hello() { 
     // authInfo here will be pre-filled with the principal, assuming 
     // you didn't abort the request in the filter 
     return authInfo.getPrincipal().getUsername(); 
    } 
} 

public class MainModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(AuthFilter.class); 
     bind(HelloResource.class); 
     bind(AuthInfo.class).in(RequestScoped.class); 
    } 
} 

をそして、あなたはいくつかの理由でシングルトンスコープ内のリソース(あるいはフィルタ)を入れなかった場合でも、あなたは常にProvider<AuthInfo>の代わりAuthInfoを注入することができます。

更新

フィルタはシングルトンスコープでデフォルトしないことであるという点で、私は多少間違っていたようです。実際、たとえそれが束縛されていないとしても、シングルトンのように振る舞うようです。 JAX-RSコンテナの起動時に作成されます。したがって、Provider<AuthInfo>をフィルタに注入する必要があります。実際には、AuthInfoがリクエストスコープにバインドされている間にフィルタに直接注入されると、コンテナの起動は失敗します。リソース(明示的にシングルトンとしてバインドされていない場合)は、直接注入でもOKです。

githubに作業プログラムをアップロードしました。

+0

ありがとうございます!プリンシパルをリソースメソッドに直接直接注入する方法があることを望んでいましたが、そのアイデアをあきらめる必要があります;)コードを試してみると、リソースメソッドが実行される。私が逃したものを驚かせて... – Stine

+0

auth info request scopedを作成することで、私のトラブルに関して新しい質問を作成するべきですか? – Stine

+0

@Stine、私の更新を見てください)あなたは2番目の部分で高速でした:) –

関連する問題