簡體   English   中英

球衣和HK2-正在注入當前用戶

[英]Jersey and HK2 - Injecting current user

我正在使用jersey 2.17和HK2創建一個簡單的rest應用。 我有一個ContainerRequestFilter ,它拒絕任何沒有“ currentuser” cookie的請求。

我有這樣的事情:

@Path("/users")
public class UserResource { 

      private UserService userService; 

      @GET
      @Path("/orders")
      @Produces("application/json")
      public List<Order> findOrdersOfCurrentUser() { 
            // some ugly code to access headers, extract cookies, and finally
            // extract username (a String) from a particular cookie

            return this.userService.findOrdersByUsername(username) ; 
      }
}

我想編寫比這更優雅的東西。 像這樣:

 @Path("/users")
 public class UserResource { 

          private UserService userService; 

          @CurrentUsername
          private String currentUser; 

          @GET
          @Path("/orders")
          @Produces("application/json")
          public List<Order> findOrdersOfCurrentUser() { 
                return this.userService.findOrdersByUsername(username) ; 
          }
    }

我對hk2真的很陌生,並且真的很難找到方法。

我只是在要求正確的接口來實現(或擴展類)。

您正在尋找的東西並非易事。 解決此問題的一種方法是在ContainerRequestFilter內設置SecurityContext ,如此處所示 這不涉及與HK2的任何直接交互。 然后,您可以在資源類中注入SecurityContext 並吸引用戶

securityContext.getUserPrincipal().getName();

如果您確實想使用自定義注解注入用戶名,則需要創建InjectionResolver請參閱定義自定義注入注解 。您可以將ContainerRequestContext (傳遞給ContainerRequestFilter的filter方法的相同注入)或SecurityContext注入InjectionResolver 。例如

過濾

@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 {   
}

InjectionResolver

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;          
    } 
}

資源

@Path("user")
public class UserResource {

    @CurrentUser 
    private User user;

    @GET
    public Response getCurrentUser() {
        return Response.ok(user.getUsername()).build();
    }
}

現在我不太確定第二種方法,至少關於過濾器的部分是@PreMatching過濾器。 如果我不進行預匹配,則User為null。 看來ContainerRequestContext還沒有我們設置的屬性,這意味着正在發生的情況是在過濾器之前調用了InjectResolver 我將需要對此進行調查。 使其成為預匹配項,不需要IMO。

但是就我個人而言,我會采用第一種方法,僅使用SecurityContext 我上面提供的鏈接中有一個完整的示例。 通過這種方法,您可以根據需要利用Jersey的RolesAllowedDynamicFeature

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM