我認爲你最好的選擇是在請求範圍內使用中間值。假設您沒有將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。
謝謝!希望有一種方法可以更直接地將主體注入到資源方法中,但是我猜想我必須放棄這個想法;)當我試用你的代碼時,我的資源方法是auth信息的主體尚未設置執行。想知道我錯過了什麼... – Stine
猜猜我應該創建一個關於使auth信息請求作用域的麻煩的新問題? – Stine
@Stine,請參閱我的更新)你快第二部分:) –