Как в Dropwizard 0.8.4 использовать аннотацию roleAllowed?

В новых версиях dropwizard вы можете создать базовый фильтр аутентификации, который принимает авторизатор и аутентификатор. Затем каждый ресурс можно пометить тегом @RolesAllowed.

В 0.8.4 вы не можете создать авторизатор таким же образом - но тег RolesAllowed остается. Как использовать тег rolesAllowed, чтобы добиться того же поведения, что и в более поздних версиях?

Dropwizard 0.8.4 был выпущен 26 августа 2015 года. Есть ли причина, по которой вы хотите версию, которой уже почти три года?
user9455968 08.05.2018 12:31

В основном это устаревшая проблема, которая будет решена достаточно скоро. Но пока я ограничен этой версией, и мне любопытно, потому что простое существование аннотации #RolesAllowed вместе с RolesAllowedDynamicFeature в этой версии подразумевает (для меня), что вам не нужно вводить пользователя #Auth в каждый ресурс для проверки ролей.

k_liaqat 08.05.2018 12:49

Эти (@RolesAllowed и RolesAllowedDynamicFeature) являются функциями Jersey, а не Dropwizard. Dropwizard не использовал их до версии 0.9.0.

Paul Samsotha 10.05.2018 09:35
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
276
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Dropwizard 0.8.x невозможно использовать @RolesAllowed из-за способа аутентификации; это не связано с тем, как Джерси использует SecurityContext. Начиная с 0.9.0, Dropwizard начал использовать SecurityContext, который Джерси использует для работы аннотации @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

Другие вопросы по теме