2017-07-28 61 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中是有,即使你不使用它。