有没有办法在Jersey中以编程方式获得会话管理或安全性,例如Web应用程序会话管理?或者,事务,会话和安全性是否都由部署Jersey应用程序的容器处理?
会话管理是部署Jersey的容器的范围.在大多数生产案例中,它将部署在执行会话管理的容器中.
下面的代码是一个简单的球衣资源示例,它获取会话对象并在会话中存储值并在后续调用中检索它们.
@Path("/helloworld") public class HelloWorld { @GET @Produces("text/plain") public String hello(@Context HttpServletRequest req) { HttpSession session= req.getSession(true); Object foo = session.getAttribute("foo"); if (foo!=null) { System.out.println(foo.toString()); } else { foo = "bar"; session.setAttribute("foo", "bar"); } return foo.toString(); } }
我认为,会议是我们应该永远在RESTful应用程序使用...
叶戈尔是对的.在服务器端,我们不应该永远保持状态一拉传统的Web应用程序.如果要构建一个分离的面向SOA的应用程序,则不需要使用任何API /框架来进行REST Web服务.如果您需要或希望在服务器端维护全局客户端 - 服务器状态,那么您将隐式构建我们可以描述为面向SOA的[Web]应用程序,但使用Jersey作为各种各样的[web]开发框架.无意中,您正在扭曲Web服务(REST或其他)的本质.您可以按照第一个答案中建议的方式进行,但您不能这样做.最终结果不是Web服务,只是使用Web服务工具构建的常规应用程序.
-_o
是的,这是可能的.泽西文件说:
通过使用@Context注释注入JAX-RS SecurityContext实例,可以获得请求的安全信息.注入的安全上下文实例提供HttpServletRequest API上可用功能的等效项.注入的安全上下文取决于实际的Jersey应用程序部署.例如,对于部署在Servlet容器中的Jersey应用程序,Jersey SecurityContext将封装来自从Servlet请求检索的安全上下文的信息.如果在Grizzly服务器上部署了Jersey应用程序,SecurityContext将返回从Grizzly请求中检索到的信息.
例:
@Path("basket") public ShoppingBasketResource get(@Context SecurityContext sc) { if (sc.isUserInRole("PreferredCustomer") { return new PreferredCustomerShoppingBasketResource(); } else { return new ShoppingBasketResource(); } }
要么
@Path("resource") @Singleton public static class MyResource { // Jersey will inject proxy of Security Context @Context SecurityContext securityContext; @GET public String getUserPrincipal() { return securityContext.getUserPrincipal().getName(); } }
或者,如果您想要开箱即用的安全注释,请检查这些文档.
Jersey还允许您自定义SecurityContext:
可以通过getSecurityContext()方法从ContainerRequestContext直接检索SecurityContext.您还可以使用setSecurityContext(SecurityContext)方法将请求上下文中的默认SecurityContext替换为自定义SecurityContext.如果在ContainerRequestFilter中设置自定义SecurityContext实例,则此安全上下文实例将用于注入JAX-RS资源类字段.这样,您就可以实现自定义身份验证筛选器,该筛选器可以设置您自己的SecurityContext以供使用.要确保提前执行自定义身份验证请求筛选器,请使用"优先级"中的常量将筛选器优先级设置为AUTHENTICATION.早期执行您的身份验证过滤器将确保所有其他过滤器,资源,
请参阅有关如何使用Jersey的请求过滤器的示例.并查看以下示例:
import javax.annotation.Priority; import javax.ws.rs.Priorities; @Provider @Priority(Priorities.AUTHENTICATION) public class AuthRequestFilter implements ContainerRequestFilter { @Context HttpServletRequest webRequest; @Override public void filter(ContainerRequestContext requestContext) throws IOException { final HttpSession session = webRequest.getSession(); requestContext.setSecurityContext(new SecurityContext() { @Override public Principal getUserPrincipal() { return new PrincipalImpl((String)session.getAttribute("USER_NAME")); } @Override public boolean isUserInRole(String s) { return false; } @Override public boolean isSecure() { return false; } @Override public String getAuthenticationScheme() { return null; } }); } }
警告!这是在泽西岛2.4中引入的.Glassfish 4.0.0使用旧版的Jersey 2.0,因此您必须使用这些技巧升级Jersey(事实证明它不能正常工作).或者更好的方法是下载Glassfish 4.0.1的每晚版本.但目前还不完全稳定.我希望新版本即将发布.
更新: 目前(2014-02-14)Glassfish 4.0.1每晚构建使用Jersey 2.5.1并且上下文注入效果很好.
杰克对会议的回应是正确的.它们特定于您执行的容器,尽管Servlet规范至少为您提供了JavaEE容器之间的可移植性.
至于安全性,您至少有机会通过使用JaaS(Java身份验证和授权服务)和servlet过滤器将其与JAX-RS特定代码分开.过滤器可用于强制执行HTTP身份验证,并且在成功验证后,使用适当的主体设置JaaS主题.您的JAX-RS资源可以检查主题上的相应主体.由于您控制整个堆栈,您应该能够依赖资源中经过身份验证的用户(但要对此进行测试!),并且您可以根据资源代码中的当前操作强制执行授权.