Jax-RS过滤器将对象传递给资源 [英] Jax-RS Filter pass object to resource

查看:69
本文介绍了Jax-RS过滤器将对象传递给资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将用于身份验证的用户对象在过滤器中传递给资源.有可能吗?

I want to pass the user object I use for authentication in a filter to the resource. Is it possible?

我正在使用wildfly 10(resteasy 3)

I'm using wildfly 10 (resteasy 3)

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

  @Inject
  private UserDao userDao;

  @Override
  public void filter(ContainerRequestContext requestContext) throws IOException {

    logger.warn("Filter");
    String uid = requestContext.getHeaderString("Authorization");
    User user;
    if((user = validateUser(uid)) == null) {
        requestContext.abortWith(
                Response.status(Response.Status.UNAUTHORIZED).build());
    }
  }

  private User validateUser(String uid) {
    return userDao.getById(uid);
  }
}

推荐答案

我有两种方法可以做到这一点.第一种也许是更标准的方式,但同时也是更多的代码.最终,您会将用户注入到请求中.但是,此解决方案所需的第一件事是校长.一个非常简单的例子可能是:

There are two ways I could see to do this. The first is, perhaps, the more standard way but is also more code. Ultimately you'll inject the user as part of the request. However, the first thing you need for this solution is a Principal. A very simple one might be:

import java.security.Principal;

...

public class UserPrinicipal implements Prinicipal {
  // most of your existing User class but needs to override getName()
}

然后,在您的过滤器中:

Then, in your filter:

...
User user;
if((user = validateUser(uid)) == null) {
    requestContext.abortWith(
            Response.status(Response.Status.UNAUTHORIZED).build());
}

requestContext.setSecurityContext(new SecurityContext() {
    @Override
    public Principal getUserPrincipal() {
        return user;
    }
    @Override
    public boolean isUserInRole(String role) {
        // whatever works here for your environment
    }
    @Override
    public boolean isSecure() {
        return containerRequestContext.getUriInfo().getAbsolutePath().toString().startsWith("https");
    }
    @Override
    public String getAuthenticationScheme() {
        // again, whatever works
    }
});

在需要用户的类中,您可以执行以下操作:

In the class where you want the User, you could do something like:

@Path("/myservice")
public class MyService {
    @Context
    private SecurityContext securityContext;

    @Path("/something")
    @GET
    public Response getSomething() {
        User user = (User)securityContext.getUserPrincipal();
    }
}

我已经以这种方式实现了它,并且效果很好.但是,一种可以说更简单的方法是将用户存储在会话中:

I've implemented it this way and it works pretty well. However, an arguably simpler way is to just store the user in the session:

@Context
private HttpServletRequest request;

...

User user;
if((user = validateUser(uid)) == null) {
    requestContext.abortWith(
            Response.status(Response.Status.UNAUTHORIZED).build());
}

request.getSession().setAttribute("user", user);

然后,为您服务:

@Path("/myservice")
public class MyService {
    @Context
    private SecurityContext securityContext;

    @Path("/something")
    @GET
    public Response getSomething(@Context HttpServletRequest request) {
        User user = (User)request.getSession().getAttribute("user");
    }
}

第二种方法的缺点是您实际上不再是无状态服务,因为您将状态存储在某个地方.但是,即使您不使用HttpSession,它也在那里.

The downside of the second method is that you are really no longer a stateless service as you're storing state somewhere. But the HttpSession is there even if you don't use it.

这篇关于Jax-RS过滤器将对象传递给资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆