2017-07-28 65 views
0

我想通过我在过滤器中使用的身份验证该资源的用户对象。可能吗?JAX-RS滤波器通对象资源

我使用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); 
    } 
} 

回答

1

有两种方法,我可以看到这样做。第一种可能是更标准的方法,但也是更多的代码。最终你会注入用户作为请求的一部分。但是,你需要的解决方案的第一件事是Principal。一个很简单的一个可能是:

import java.security.Principal; 

... 

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

然后,在你的过滤器:

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

在你想要的用户,你可以这样做的类:

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

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

我“VE这种方式实现它,它工作得很好。但是,可以说是比较简单的方法是只在用户存储在会话:

@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中是有,即使你不使用它。