В новых версиях dropwizard вы можете создать базовый фильтр аутентификации, который принимает авторизатор и аутентификатор. Затем каждый ресурс можно пометить тегом @RolesAllowed.
В 0.8.4 вы не можете создать авторизатор таким же образом - но тег RolesAllowed остается. Как использовать тег rolesAllowed, чтобы добиться того же поведения, что и в более поздних версиях?
В основном это устаревшая проблема, которая будет решена достаточно скоро. Но пока я ограничен этой версией, и мне любопытно, потому что простое существование аннотации #RolesAllowed вместе с RolesAllowedDynamicFeature в этой версии подразумевает (для меня), что вам не нужно вводить пользователя #Auth в каждый ресурс для проверки ролей.
Эти (@RolesAllowed и RolesAllowedDynamicFeature) являются функциями Jersey, а не Dropwizard. Dropwizard не использовал их до версии 0.9.0.




В 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>
После этого все должно заработать. Я выложу все классы, которые использовал для тестирования.
ExamplePrincipalpublic 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;
}
}
ExampleAuthenticatorpublic 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();
}
}
ExampleAuthorizerpublic 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";
}
}
ExampleConfigurationpublic class ExampleConfiguration extends Configuration {
private String name;
@JsonProperty
public String getName() {
return this.name;
}
@JsonProperty
public void setName(String name) {
this.name = name;
}
}
ExampleApplicationpublic 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.ymlname: "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