2016-09-14 100 views
0

我正在使用Jersey + Jetty + Dropwizard + Hibernate创建Web服务。在Jersey web服务中设置角色

比方说,我有这样一个网络资源:

@Path("/") 
@PermitAll 
public class Resource { 
    @RolesAllowed("user") 
    @GET 
    public String get() { return "GET"; } 


@RolesAllowed("admin") 
@POST 
public String post(String content) { return content; } 

@Path("sub") 
public SubResource getSubResource() { 
    return new SubResource(); 
} 
} 

我知道你可以用HttpServletRequest.isUserInRole检查用户的角色。

的问题是,我该如何分配开始与角色?泽西如何知道要为isUserInRole方法返回什么,或知道如何过滤人们根据他们的角色没有获得特定资源?

我没有web.xmlwebdefault.xml,所以定义应该在其他地方完成。

+0

你看的文档为[Dropwizard验证(http://www.dropwizard.io/1.0.0/docs/manual/auth.html)?它支持Basic和OAuth。还有第三方[JWT的lib](https://github.com/ToastShaman/dropwizard-auth-jwt)。所有这些角色的东西都由框架处理。除非你有这些解决方案并且你没有为你工作,并且你想自己创建 –

回答

0

您必须提供一个支持@RolesAllowed(“admin”)批注的提供者类,然后您必须在应用程序中注册提供者类。正常情况下,它是在web.xml中完成的,但是因为您没有使用它,你必须自己提供。相关示例可以发现here

+0

这个例子包括在web.xml文件中进行设置,我说我没有 –

+0

那么你是如何加载你的泽西servlet的。你必须使用一些配置文件或注释(@webservlet)。你必须在那里加载它。 –

+0

我得到了config.yml文件和资源等的所有配置与dropwizard的配置类 –

0

Jersey使用自己的机制来检查角色(请参阅SecurityContext接口),但是如果未明确设置,它将回退到容器验证,通常使用JaaS来实现。如果你有web.xml,你可以在那里配置它的基本知识。

然后再次频繁地进行身份验证的方式不同。如果您可以手动登录用户,例如有可以检查名称/密码的服务,那么您可以实施一个ContainerRequestFilter,这将填充安全上下文,使得@RolesAllowed注释可以正常工作。

例如:

更新基于意见

用户种源方法日志:

@Path("some/login/path") 
public void login() { 
    String name = getUsernameFromRequest(); 
    String password = // like above 
    User user = loginService.login(name, password); 
    request.getSession().addAttribute("user", user); 
} 

初始化安全上下文中的过滤器的所有请求。

@Priority(Priorities.AUTHENTICATION) 
public class JerseySecurityContextFilter implements ContainerRequestFilter { 

    public void filter(final ContainerRequestContext context) throws IOException { 
    User user = getUserFromSession(); 
    if (user != null) { 
     // this sets security context for the rest of processing 
     // it should make @RolesAllowed work 
     context.setSecurityContext(new JerseySecurityContext(user); 
    } 
} 

final class JerseySecurityContext implements SecurityContext { 

    private final User user; 

    public JerseySecurityContext(final User user) { 
     this.user = user; 
    } 

    public boolean isUserInRole(final String roleName) { 
     return user.hasRole(roleName); 
    } 

    public Principal getUserPrincipal() { 
     return new Principal() { 
      public String getName() { 
       return user.getName(); 
      } 
     }; 
    } 

    public String getAuthenticationScheme() { 
     return null; 
    } 
} 

如果您愿意使用JAAS,那么你就必须在你的应用程序配置配置安全性。这些是嵌入式Jetty的一些示例。

+0

初始化现在,我得到了一个名为loginUser的资源方法,得到一个dropwizard的应用程序类用户名和密码,并检查它是否与数据库中的相匹配。如何在调用此特定资源类时告诉JerseySecurityContextFilter运行? –

+0

当用户登录并且您的资源方法运行时,请创建一个会话并将其放入其中。然后过滤器将能够检查用户是否存在于会话中。如果是的话,他是登录的,如果不是,他不是。您可以使用几种方法将过滤器添加到球衣中。其中之一是用'ResourceConfig'注册过滤器类。 –

+0

我现在意识到我误导了你,建议在过滤器中登录用户。如果你使用了基本身份验证之类的东西,那很好。如果您使用专用表单或类似登录方法的资源支持,请将用户对象放入会话中,并将其从过滤器中的会话中拉出。其余的可以保持不变。如果您愿意,我可以更新代码示例。 –