问题在DropWizard自定义授权 [英] Issue with custom Authorization in DropWizard

查看:638
本文介绍了问题在DropWizard自定义授权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加自定义授权,dropwizard但不能successed。

I am trying to add custom authorization in dropwizard but not able to successed.

我添加了dropwizard定制的身份验证通过绑定到authFactory

I have a custom authentication added for dropwizard by binding it to authFactory

Authenticator ssoAuthenticator = createSSOAuthenticator(configuration.getSsoGrantClientConfiguration());
environment.jersey().register(AuthFactory.binder(
                    new SSOTokenAuthFactory<SSOGrant>(
                                       ssoAuthenticator,
                                          SYSTEM_PREFIX,
                                         SSOGrant.class))
 );

和增加对授权的dynamicfeature

and adding a dynamicfeature for authorization

environment.jersey().register(PermissionDynamicFeature.class);

下面是注释创建

@Documented
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER,java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})
public @interface PermissionsAllowed {
    String[] value();
}

我检查注释是否在方法present然后登记一个过滤

I am checking whether the annotation is present on the method and then registering a filter

public class PermissionDynamicFeature implements DynamicFeature {
@Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext configuration) {

        final AnnotatedMethod am = new AnnotatedMethod(resourceInfo.getResourceMethod());
        final Annotation[][] parameterAnnotations = am.getParameterAnnotations();
            for (Annotation[] annotations : parameterAnnotations) {
                for (Annotation annotation : annotations) {
                    if (annotation instanceof PermissionsAllowed) {
                        configuration.register(new RolesAllowedRequestFilter(((PermissionsAllowed)annotation).value()));
                        return;
                    }
                }
            }
        }



    //@Priority(Priorities.USER) // authorization filter - should go after any authentication filters
    private static class RolesAllowedRequestFilter implements ContainerRequestFilter {

        private final boolean denyAll;
        private final String[] rolesAllowed;

        RolesAllowedRequestFilter() {
            this.denyAll = true;
            this.rolesAllowed = null;
        }

        RolesAllowedRequestFilter(final String[] rolesAllowed) {
            this.denyAll = false;
            this.rolesAllowed = (rolesAllowed != null) ? rolesAllowed : new String[] {};
        }

        @Override
        public void filter(final ContainerRequestContext requestContext) throws IOException {
            if (!denyAll) {
                if (rolesAllowed.length > 0 && !isAuthenticated(requestContext)) {
                    throw new ForbiddenException(LocalizationMessages.USER_NOT_AUTHORIZED());
                }

                for (final String role : rolesAllowed) {
                    if (requestContext.getSecurityContext().isUserInRole(role)) {
                        return;
                    }
                }
            }

            throw new ForbiddenException(LocalizationMessages.USER_NOT_AUTHORIZED());
        }

        private static boolean isAuthenticated(final ContainerRequestContext requestContext) {
            return requestContext.getSecurityContext().getUserPrincipal() != null;
        }
    }
}

我只是想基于相同的行作为RolesAllowed过滤器来构建我的授权。

I am just trying to build my authorization based on the same lines as RolesAllowed filter.

这是我面临的问题是,授权过滤器验证之前调用。
我所缺少的,这样认证是第一和授权过滤器是后来被称为?

The issue that i am facing is that the Authorization filter is called before the authentication. What i am missing so that the authentication happens first and the authorization filter is called later?

同样的情况。

environment.jersey().register(RolesAllowedDynamicFeature.class);

RolesAllowedDynamicFeature称为认证甚至发生之前。

RolesAllowedDynamicFeature is called even before the authentication happens.

推荐答案

所以根据您的回答,我写了一个测试,我相信我可以告诉你什么是这里的问题。

so based on your answers I wrote up a test and I believe I can tell you what's the issue here.

您使用的是提供身份验证令牌Authfactory不是请求过滤器。总部位于新泽西州的文件上,这是一个请求的执行顺序:

The Authfactory you are using to provide Authentication tokens is not a request Filter. based on the documentation of jersey, this is the execution order of a request:

https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e9976

问题如下:

所有的请求过滤器会永远是你绑定执行之前执行。在请求的时候,球衣甚至不知道它是否需要任何绑定到你的方法在所有。为什么要创造什么,它就会在执行前一个过滤器可能会拒绝这个请求。

ALL request filter will always be executed before your binding is executed. At the time of the request, jersey doesn't even know if it needs to bind anything to your method at all. Why should it create anything, a filter might reject the request before it gets to execution.

因此​​,在短期,注释与@Auth你的资源方法简单地增加注射粘结剂你的球衣环境。你可以在这里阅读定制注塑:

So in short, annotating your resource method with @Auth simply adds an injection binder to your jersey environment. You can read about custom injection here:

https://jersey.java.net/documentation/latest/ioc.html

这显然是正常工作,是相当方便的,但不是你想要的。
你想要的是之前通过任何过滤器拒绝请求。为此,你必须写一个请求过滤器。用正确的优先级注释它,一切都应该工作正常。

This obviously works correctly and is quite handy, however not what you want. What you want is to reject a request before it passed through any filter. For this you MUST write a request filter. Annotate it with the correct priority and everything should be working fine.

您可以有一个想想有一个RequestFilter和你的Authenticator提取您的身份验证逻辑到一个共同的类(你已经做了),然后注册相同的类,因此让这验证提供者,同时还根据验证其请求过滤

You could have a think about extracting your auth logic into a common class (Which you already did) and then register the same class with a RequestFilter and your Authenticator, therefore keeping the Auth provider, while still having request filtering based on Authentication.

run(...) {

   myAuthStuff = create()
   jersey.register(MyAuthRequstFilter(myAuthStuff));
   jersey.register(MyAuthInjectionBinder(myAuthStuff));

}

添加一个缓存,你会不会担心调用同样的事情两次。

Add a cache and you won't have to worry about calling the same thing twice.

我相信dropwizard并没有打算用这个过滤器来工作。看来他们的意图是注入AUTH环境到资源的方法做身份验证等在那里。不是我的preferred解决方案,但它可以工作。

I believe dropwizard did not intend this to work with filters. It appears their intention was to inject the auth context into a resource method and do authentication etc in there. Not my preferred solution, but it could work.

所以总结东西了:

你想要做什么是不开箱通过dropwizard支持。解决的办法是其溶液扩展到一个请求滤波器。

What you want to do is not supported by dropwizard out of the box. The solution is to extend their solution into a request filter.

希望帮助,

阿图尔

这篇关于问题在DropWizard自定义授权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆