diff --git a/pom.xml b/pom.xml
index ba5449b..fc2daba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,14 @@
dropwizard-hibernate
${dropwizard.version}
-
+
+
+ io.dropwizard
+ dropwizard-auth
+ ${dropwizard.version}
+
+
+
diff --git a/src/main/java/someshbose/github/io/HelloWorldApplication.java b/src/main/java/someshbose/github/io/HelloWorldApplication.java
index 4ecb3fc..6986144 100644
--- a/src/main/java/someshbose/github/io/HelloWorldApplication.java
+++ b/src/main/java/someshbose/github/io/HelloWorldApplication.java
@@ -3,9 +3,13 @@
import com.google.inject.Guice;
import com.google.inject.Injector;
import io.dropwizard.Application;
+import io.dropwizard.auth.AuthDynamicFeature;
+import io.dropwizard.auth.AuthValueFactoryProvider;
+import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import lombok.extern.slf4j.Slf4j;
+import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
import someshbose.github.io.app.config.HelloWorldApplicationModule;
import someshbose.github.io.app.config.HelloWorldApplicationConfiguration;
import someshbose.github.io.app.controller.HelloWorldApplicationResource;
@@ -14,7 +18,10 @@
import io.dropwizard.migrations.MigrationsBundle;
import io.dropwizard.hibernate.HibernateBundle;
import someshbose.github.io.app.controller.PersonResource;
-import someshbose.github.io.model.Person;
+import someshbose.github.io.domain.model.Person;
+import someshbose.github.io.domain.model.User;
+import someshbose.github.io.infra.auth.AppAuthorizer;
+import someshbose.github.io.infra.auth.AppBasicAuthenticator;
@Slf4j
public class HelloWorldApplication extends Application {
@@ -61,7 +68,7 @@ public void run(HelloWorldApplicationConfiguration configuration, Environment en
Injector injector = Guice.createInjector(new HelloWorldApplicationModule(configuration,hibernate));
registerResources(injector,environment,configuration);
registerHealthCheck(environment,configuration);
-
+ registerAuthentication(environment);
}
private void registerResources(Injector injector, Environment environment, HelloWorldApplicationConfiguration configuration){
@@ -72,5 +79,16 @@ private void registerResources(Injector injector, Environment environment, Hello
private void registerHealthCheck(Environment environment, HelloWorldApplicationConfiguration configuration){
environment.healthChecks().register("HelloWorldApplicationHealthCheck", new HelloWorldApplicationHealthCheck(configuration.getTemplate()));
}
+
+ /****** Dropwizard security - custom classes ***********/
+ private void registerAuthentication(Environment environment){
+ environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder()
+ .setAuthenticator(new AppBasicAuthenticator())
+ .setAuthorizer(new AppAuthorizer())
+ .setRealm("BASIC-AUTH-REALM")
+ .buildAuthFilter()));
+ environment.jersey().register(RolesAllowedDynamicFeature.class);
+ environment.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
+ }
}
diff --git a/src/main/java/someshbose/github/io/app/controller/HelloWorldApplicationResource.java b/src/main/java/someshbose/github/io/app/controller/HelloWorldApplicationResource.java
index 6ca381f..898a974 100644
--- a/src/main/java/someshbose/github/io/app/controller/HelloWorldApplicationResource.java
+++ b/src/main/java/someshbose/github/io/app/controller/HelloWorldApplicationResource.java
@@ -2,6 +2,7 @@
import java.util.Optional;
import java.util.concurrent.atomic.AtomicLong;
+import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -9,7 +10,9 @@
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import com.codahale.metrics.annotation.Timed;
-import someshbose.github.io.model.Saying;
+import io.dropwizard.auth.Auth;
+import someshbose.github.io.domain.model.Saying;
+import someshbose.github.io.domain.model.User;
@Path("/hello-world")
@Produces(MediaType.APPLICATION_JSON)
@@ -27,8 +30,9 @@ public HelloWorldApplicationResource(String template, String defaultName) {
}
@GET
+ @RolesAllowed({ "ADMIN"})
@Timed
- public Saying sayHello(@QueryParam("name") Optional name) {
+ public Saying sayHello(@QueryParam("name") Optional name, @Auth User user) {
final String value = String.format(template, name.orElse(defaultName));
return new Saying(counter.incrementAndGet(), value);
}
diff --git a/src/main/java/someshbose/github/io/app/controller/PersonResource.java b/src/main/java/someshbose/github/io/app/controller/PersonResource.java
index cc69895..cadfc03 100644
--- a/src/main/java/someshbose/github/io/app/controller/PersonResource.java
+++ b/src/main/java/someshbose/github/io/app/controller/PersonResource.java
@@ -13,8 +13,8 @@
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import io.dropwizard.hibernate.UnitOfWork;
-import someshbose.github.io.app.dao.PersonDao;
-import someshbose.github.io.model.Person;
+import someshbose.github.io.domain.dao.PersonDao;
+import someshbose.github.io.domain.model.Person;
@Path("/person")
@Consumes({MediaType.APPLICATION_JSON})
diff --git a/src/main/java/someshbose/github/io/app/dao/PersonDao.java b/src/main/java/someshbose/github/io/domain/dao/PersonDao.java
similarity index 89%
rename from src/main/java/someshbose/github/io/app/dao/PersonDao.java
rename to src/main/java/someshbose/github/io/domain/dao/PersonDao.java
index eb18c1b..fee9358 100644
--- a/src/main/java/someshbose/github/io/app/dao/PersonDao.java
+++ b/src/main/java/someshbose/github/io/domain/dao/PersonDao.java
@@ -1,10 +1,10 @@
-package someshbose.github.io.app.dao;
+package someshbose.github.io.domain.dao;
import java.util.List;
import org.hibernate.SessionFactory;
import io.dropwizard.hibernate.AbstractDAO;
import org.hibernate.query.Query;
-import someshbose.github.io.model.Person;
+import someshbose.github.io.domain.model.Person;
import javax.inject.Inject;
diff --git a/src/main/java/someshbose/github/io/model/Person.java b/src/main/java/someshbose/github/io/domain/model/Person.java
similarity index 97%
rename from src/main/java/someshbose/github/io/model/Person.java
rename to src/main/java/someshbose/github/io/domain/model/Person.java
index 911db00..c80c430 100644
--- a/src/main/java/someshbose/github/io/model/Person.java
+++ b/src/main/java/someshbose/github/io/domain/model/Person.java
@@ -1,4 +1,4 @@
-package someshbose.github.io.model;
+package someshbose.github.io.domain.model;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
diff --git a/src/main/java/someshbose/github/io/model/Saying.java b/src/main/java/someshbose/github/io/domain/model/Saying.java
similarity index 84%
rename from src/main/java/someshbose/github/io/model/Saying.java
rename to src/main/java/someshbose/github/io/domain/model/Saying.java
index 6857673..4b4978f 100644
--- a/src/main/java/someshbose/github/io/model/Saying.java
+++ b/src/main/java/someshbose/github/io/domain/model/Saying.java
@@ -1,4 +1,4 @@
-package someshbose.github.io.model;
+package someshbose.github.io.domain.model;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/src/main/java/someshbose/github/io/domain/model/User.java b/src/main/java/someshbose/github/io/domain/model/User.java
new file mode 100644
index 0000000..7352ae8
--- /dev/null
+++ b/src/main/java/someshbose/github/io/domain/model/User.java
@@ -0,0 +1,32 @@
+package someshbose.github.io.domain.model;
+
+import java.security.Principal;
+import java.util.Set;
+
+public class User implements Principal {
+ private final String name;
+
+ private final Set roles;
+
+ public User(String name) {
+ this.name = name;
+ this.roles = null;
+ }
+
+ public User(String name, Set roles) {
+ this.name = name;
+ this.roles = roles;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getId() {
+ return (int) (Math.random() * 100);
+ }
+
+ public Set getRoles() {
+ return roles;
+ }
+}
diff --git a/src/main/java/someshbose/github/io/infra/auth/AppAuthorizer.java b/src/main/java/someshbose/github/io/infra/auth/AppAuthorizer.java
new file mode 100644
index 0000000..693cb1d
--- /dev/null
+++ b/src/main/java/someshbose/github/io/infra/auth/AppAuthorizer.java
@@ -0,0 +1,12 @@
+package someshbose.github.io.infra.auth;
+
+import io.dropwizard.auth.Authorizer;
+import someshbose.github.io.domain.model.User;
+
+public class AppAuthorizer implements Authorizer
+{
+ @Override
+ public boolean authorize(User user, String role) {
+ return user.getRoles() != null && user.getRoles().contains(role);
+ }
+}
diff --git a/src/main/java/someshbose/github/io/infra/auth/AppBasicAuthenticator.java b/src/main/java/someshbose/github/io/infra/auth/AppBasicAuthenticator.java
new file mode 100644
index 0000000..0094712
--- /dev/null
+++ b/src/main/java/someshbose/github/io/infra/auth/AppBasicAuthenticator.java
@@ -0,0 +1,31 @@
+package someshbose.github.io.infra.auth;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.basic.BasicCredentials;
+import someshbose.github.io.domain.model.User;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+public class AppBasicAuthenticator implements Authenticator
+{
+ private static final Map> VALID_USERS = ImmutableMap.of(
+ "guest", ImmutableSet.of(),
+ "user", ImmutableSet.of("USER"),
+ "admin", ImmutableSet.of("ADMIN", "USER")
+ );
+
+ @Override
+ public Optional authenticate(BasicCredentials credentials) throws AuthenticationException
+ {
+ if (VALID_USERS.containsKey(credentials.getUsername()) && "password".equals(credentials.getPassword()))
+ {
+ return Optional.of(new User(credentials.getUsername(), VALID_USERS.get(credentials.getUsername())));
+ }
+ return Optional.empty();
+ }
+}