您正在寻找的东西并非易事。处理这个问题的一种方法是设置SecurityContext
在 - 的里面ContainerRequestFilter
, as 在这里看到。这不涉及与 HK2 的任何直接交互。然后你可以注入SecurityContext
在您的资源类中。并通过以下方式获取用户
securityContext.getUserPrincipal().getName();
如果您确实想使用自定义注释注入用户名,则需要创建一个InjectionResolver
(请参阅定义自定义注入注释。你可以注射ContainerRequestContext
(与传递给过滤器方法的相同ContainerRequestFilter
) 或者SecurityContext
进入InjectionResolver
。例如
Filter
@Provider
@PreMatching
public class UserFilter implements ContainerRequestFilter {
public static final String USER_PROP = "user";
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
requestContext.setProperty(USER_PROP, new User("peeskillet"));
}
}
注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CurrentUser {
}
注入解析器
public class CurrentUserInjectionResolver implements InjectionResolver<CurrentUser> {
javax.inject.Provider<ContainerRequestContext> requestContext;
@Inject
public CurrentUserInjectionResolver(
javax.inject.Provider<ContainerRequestContext> requestContext) {
this.requestContext = requestContext;
}
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> sh) {
if (User.class == injectee.getRequiredType()) {
return requestContext.get().getProperty(UserFilter.USER_PROP);
}
return null;
}
@Override
public boolean isConstructorParameterIndicator() { return false; }
@Override
public boolean isMethodParameterIndicator() { return false; }
}
绑定 InjectionResolver
@Provider
public class UserFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new AbstractBinder(){
@Override
public void configure() {
bind(CurrentUserInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<CurrentUser>>(){})
.in(Singleton.class);
}
});
return true;
}
}
Resource
@Path("user")
public class UserResource {
@CurrentUser
private User user;
@GET
public Response getCurrentUser() {
return Response.ok(user.getUsername()).build();
}
}
现在我不太确定第二种方法,至少关于过滤器的部分是@PreMatching
筛选。如果我不进行预匹配,User
将为空。看来ContainerRequestContext
还没有我们设置的属性,这意味着正在发生的事情是InjectResolver
在过滤器之前被调用。我需要调查一下。使其成为预匹配,IMO 不应该是必需的。
但就我个人而言,我会采用第一种方法,只需使用SecurityContext
。完整的示例位于我上面提供的链接中。通过这种方法,您可以利用泽西岛的RolesAllowedDynamicFeature如果需要的话。