首页 > 解决方案 > 在 Dropwizard 0.8.4 中,如何使用 rolesAllowed 注释?

问题描述

在新的 dropwizard 版本中,您可以创建一个基本的身份验证过滤器,该过滤器采用授权人和身份验证器。@RolesAllowed然后可以用标签对每个资源进行注释。

在 0.8.4 中,您不能以相同的方式创建授权人 - 但RolesAllowed标签仍然存在。您如何使用rolesAllowed标签来获得与更高版本中相同的行为?

标签: javadropwizard

解决方案


在 Dropwizard 0.8.x 中,由于身份验证的完成方式,无法使用@RolesAllowed;它与泽西岛如何使用SecurityContext. 从 0.9.0 开始,Dropwizard 开始使用SecurityContext,这是 Jersey 用来使@RolesAllowed注释工作的。

幸运的是,您只需将dropwizard-auth依赖项升级到 0.9.0,它仍然可以与 Dropwizard 0.8.4 一起使用。我实际上刚刚对此进行了测试,并且效果很好。您只需要从中排除dropwizard-core

<dependencies>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-core</artifactId>
        <version>0.8.4</version>
    </dependency>
    <dependency>
        <groupId>io.dropwizard</groupId>
        <artifactId>dropwizard-auth</artifactId>
        <version>0.9.0</version>
        <exclusions>
            <exclusion>
                <groupId>io.dropwizard</groupId>
                <artifactId>dropwizard-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

完成此操作后,它应该一切正常。我将发布我用来测试它的所有类。

ExamplePrincipal

public class ExamplePrincipal implements Principal {
    private String name;
    private List<String> roles;

    public ExamplePrincipal(String name, List<String> roles) {
        this.name = name;
        this.roles = roles;
    }
    public String getName() {
        return this.name;
    }
    public List<String> getRoles() {
        return this.roles;
    }
}

ExampleAuthenticator

public class ExampleAuthenticator implements Authenticator<BasicCredentials, ExamplePrincipal> {

    @Override
    public Optional<ExamplePrincipal> authenticate(BasicCredentials credentials) throws AuthenticationException {
        if ("peeskillet".equals(credentials.getUsername())
                && "secret".equals(credentials.getPassword())) {
            return Optional.of(new ExamplePrincipal(credentials.getUsername(), Arrays.asList("ADMIN")));
        }
        return Optional.absent();
    }
}

ExampleAuthorizer

public class ExampleAuthorizer implements Authorizer<ExamplePrincipal> {

    @Override
    public boolean authorize(ExamplePrincipal principal, String role) {
        return principal.getRoles().contains(role);
    }
}

ExampleResource

@Path("example")
public class ExampleResource {

    private String name;

    public ExampleResource(String name) {
        this.name = name;
    }

    @GET
    @RolesAllowed("ADMIN")
    public String get() {
        return "Hello " + name + "!";
    }

    @GET
    @Path("root")
    @RolesAllowed("ROOT")
    public String getRoot() {
        return "Root Access";
    }
}

ExampleConfiguration

public class ExampleConfiguration extends Configuration {

    private String name;

    @JsonProperty
    public String getName() {
        return this.name;
    }

    @JsonProperty
    public void setName(String name) {
        this.name = name;
    }
}

ExampleApplication

public class ExampleApplication extends Application<ExampleConfiguration> {

    public static void main(String...args) throws Exception {
        new ExampleApplication().run(args);
    }


    public void run(ExampleConfiguration config, Environment env) throws Exception {
        env.jersey().property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, true);
        env.jersey().register(new ExampleResource(config.getName()));

        env.jersey().register(RolesAllowedDynamicFeature.class);
        env.jersey().register(new AuthDynamicFeature(
                new BasicCredentialAuthFilter.Builder<ExamplePrincipal>()
                        .setAuthenticator(new ExampleAuthenticator())
                        .setAuthorizer(new ExampleAuthorizer())
                        .setRealm("ExampleRealm")
                        .buildAuthFilter()
        ));
        env.jersey().register(new AuthValueFactoryProvider.Binder<ExamplePrincipal>(ExamplePrincipal.class));
    }
}

example.yml

name: "Peeskillet"

要测试应用程序,您只需运行以下 cURL 命令

curl -i -u peeskillet:secret http://locahost:8080/example

如果您转到需要用户的example/root端点ROOT,您将看到 403 Forbidden 响应

url -i -u peeskillet:secret http://locahost:8080/example/root

推荐阅读