2014-01-09 66 views
6

我正在用Guice和RESTEasy一起開發一個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直接注入到過濾器中,而綁定到請求範圍,則容器啓動將失敗。資源(如果不是明確地綁定爲單身人士)雖然可以直接注入。

我上傳了工作程序到github

+0

謝謝!希望有一種方法可以更直接地將主體注入到資源方法中,但是我猜想我必須放棄這個想法;)當我試用你的代碼時,我的資源方法是auth信息的主體尚未設置執行。想知道我錯過了什麼... – Stine

+0

猜猜我應該創建一個關於使auth信息請求作用域的麻煩的新問題? – Stine

+0

@Stine,請參閱我的更新)你快第二部分:) –