Shiro与SAML2在卡拉夫与JAX-RS(泽西岛)

时间:2014-03-14 16:51:15

标签: jersey shiro saml-2.0 apache-karaf

我正在创建一个在Karaf中作为OSGi容器运行的应用程序,并使用OSGi HTTP Service和Jersey来公开REST API。我需要添加SAML2身份验证和基于权限的授权。我想在Shiro中使用基于注释的方法,因为Spring似乎正在逐渐远离OSGi。我的问题:

  1. Shiro与SAML罐子是否适合OSGi环境?
  2. 我想使用WSO2作为身份提供者。 Shiro和WSO2是否有任何共同的注意事项?
  3. 对于使用注释,Shiro文档表明我需要放置AspectJ / Spring / Guice jar - 这在OSGi环境中仍然有效吗?我更喜欢Guice满足我所有的DI需求。
  4. 从Shiro用户那里获得一些见解会很棒。

    更新

    我正在使用这个项目:osgi-jax-rs-connector。因此,我使用Guice-Peaberry来注册带有@Path或@Provider注释的接口的OSGi服务,该工具负责将它们转换为REST资源。 (类似于pax-whiteboard?)。我计划将我的过滤器类似地公开为OSGi服务,然后将它们与资源一起动态添加。

    在以前的项目中我曾经在OSGi中遇到过AspectJ的头痛,我不得不从Karaf切换到香草Equinox,因为昼夜平分点编织挂钩不同意Karaf(其中包括来自白羊座的堆栈痕迹)。那么,像shiro-jersey这样做会更好吗?

2 个答案:

答案 0 :(得分:1)

我确定它是可行的,尽管我已经看到一些限制/问题突然出现。 对于 1)没有尝试过,虽然你需要确保你告诉pax-web和jetty它,它需要将它添加到jetty.xml,它甚至可能需要添加一个片段捆绑到pax-web-jetty,以便可以加载所需的类。这很可能是你的第一个未被发现的问题 2)不知道WSO2所以不知道 3)如果你想使用注释,要小心。对于Guice来说,你最需要使用Peaberry因为afaik Guice不是" OSGi-fied"然而。由于类加载器的限制,在OSGi环境中使用AspectJ并不是一个好主意。如果你有编译时编织它应该没问题,但运行时编织将是一个挑战。

更新: 完全忘了它,但有一个Pax Shiro项目可用,也许这可以是一个很好的起点,让您的设置正确的阵容。

答案 1 :(得分:1)

为了读者的利益,我正在分享我在对现有工具进行一些研究后得出的解决方案。首先,简单的部分:在OSGi环境中使用Shiro注释。我最后编写了下面的类,因为开发人员共享的大多数Shiro-Jersey适配器都基于Jersey 1.x。


    @Provider
    public class ShiroAnnotationResourceFilter implements ContainerRequestFilter {

        private static final Map, AuthorizingAnnotationHandler> ANNOTATION_MAP = new HashMap, AuthorizingAnnotationHandler>();

        @Context
        private ResourceInfo resourceInfo;

        public ShiroAnnotationResourceFilter() {
            ANNOTATION_MAP.put(RequiresPermissions.class,
                    new PermissionAnnotationHandler());
            ANNOTATION_MAP.put(RequiresRoles.class, new RoleAnnotationHandler());
            ANNOTATION_MAP.put(RequiresUser.class, new UserAnnotationHandler());
            ANNOTATION_MAP.put(RequiresGuest.class, new GuestAnnotationHandler());
            ANNOTATION_MAP.put(RequiresAuthentication.class,
                    new AuthenticatedAnnotationHandler());
        }

        public void filter(ContainerRequestContext context) throws IOException {

            Class resourceClass = resourceInfo.getResourceClass();
            if (resourceClass != null) {
                Annotation annotation = fetchAnnotation(resourceClass
                        .getAnnotations());
                if (annotation != null) {
                    ANNOTATION_MAP.get(annotation.annotationType())
                            .assertAuthorized(annotation);
                }
            }

            Method method = resourceInfo.getResourceMethod();
            if (method != null) {
                Annotation annotation = fetchAnnotation(method.getAnnotations());
                if (annotation != null) {
                    ANNOTATION_MAP.get(annotation.annotationType())
                            .assertAuthorized(annotation);
                }
            }
        }

        private static Annotation fetchAnnotation(Annotation[] annotations) {
            for (Annotation annotation : annotations) {
                if (ANNOTATION_MAP.keySet().contains(annotation.annotationType())) {
                    return annotation;
                }
            }
            return null;
        }
    }

完整的项目是here。 以上内容涉及我的问题的第3部分。

对于带有SAML的Shiro,我使用Servicemix包装的openSAML jar,它似乎一直工作到现在为止。但我不得不写一些代码来使Shiro与SAML2一起工作。它与shiro-cas几乎在同一条线上,但与其他IdP一起使用时更为通用。代码有点大,所以共享项目的链接,而不是将类复制到SO。它可以找到here

现在我的代码和我的IdP之间有一些抽象,WSO2集成看起来有点简单。

P.S。感谢Achim的意见和建议。