原文: https://howtodoinjava.com/dropwizard/dropwizard-basic-auth-security-example/

使用 dropwizard,我们了解了创建 REST API编写客户端代码添加运行状况检查过滤器的知识。 在本教程中,我们将学习使用基本认证基于用户名/密码的认证和基于基于角色的授权功能添加到 REST API 中。

  1. Table of Contents
  2. Include Dropwizard Auth Module Maven Dependency
  3. Add Custom Principal Object
  4. Add Custom Authenticator
  5. Add Custom Authorizer
  6. Configure BasicCredentialAuthFilter
  7. Secure REST APIs with @Auth Annotation
  8. Test Dropwizard Basic Auth Code

包含 Dropwizard Auth 模块的 Maven 依赖项

认证功能在 dropwizard 应用中作为单独的模块添加。

  1. <properties>
  2. <dropwizard.version>1.0.0</dropwizard.version>
  3. </properties>
  4. <dependency>
  5. <groupId>io.dropwizard</groupId>
  6. <artifactId>dropwizard-auth</artifactId>
  7. <version>${dropwizard.version}</version>
  8. </dependency>

添加自定义主体对象

在安全性方面,主体对象表示已为其提供凭据的用户。 它实现了java.security.Principal接口。

  1. package com.howtodoinjava.rest.auth;
  2. import java.security.Principal;
  3. import java.util.Set;
  4. public class User implements Principal {
  5. private final String name;
  6. private final Set<String> roles;
  7. public User(String name) {
  8. this.name = name;
  9. this.roles = null;
  10. }
  11. public User(String name, Set<String> roles) {
  12. this.name = name;
  13. this.roles = roles;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public int getId() {
  19. return (int) (Math.random() * 100);
  20. }
  21. public Set<String> getRoles() {
  22. return roles;
  23. }
  24. }

添加自定义认证器

Authenticator类负责验证基本认证标头中包含的用户名/密码凭证。 在企业应用中,您可以从数据库中获取用户密码,如果密码匹配,则将用户角色设置为主体对象。 在 dropwizard 中,您将需要实现io.dropwizard.auth.Authenticator接口以放置您的应用逻辑。

  1. package com.howtodoinjava.rest.auth;
  2. import io.dropwizard.auth.AuthenticationException;
  3. import io.dropwizard.auth.Authenticator;
  4. import io.dropwizard.auth.basic.BasicCredentials;
  5. import java.util.Map;
  6. import java.util.Optional;
  7. import java.util.Set;
  8. import com.google.common.collect.ImmutableMap;
  9. import com.google.common.collect.ImmutableSet;
  10. public class AppBasicAuthenticator implements Authenticator<BasicCredentials, User>
  11. {
  12. private static final Map<String, Set<String>> VALID_USERS = ImmutableMap.of(
  13. "guest", ImmutableSet.of(),
  14. "user", ImmutableSet.of("USER"),
  15. "admin", ImmutableSet.of("ADMIN", "USER")
  16. );
  17. @Override
  18. public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException
  19. {
  20. if (VALID_USERS.containsKey(credentials.getUsername()) && "password".equals(credentials.getPassword()))
  21. {
  22. return Optional.of(new User(credentials.getUsername(), VALID_USERS.get(credentials.getUsername())));
  23. }
  24. return Optional.empty();
  25. }
  26. }

添加自定义授权器

Authorizer类负责匹配角色,并确定是否允许用户执行某些操作。

  1. package com.howtodoinjava.rest.auth;
  2. import io.dropwizard.auth.Authorizer;
  3. public class AppAuthorizer implements Authorizer<User>
  4. {
  5. @Override
  6. public boolean authorize(User user, String role) {
  7. return user.getRoles() != null && user.getRoles().contains(role);
  8. }
  9. }

配置BasicCredentialAuthFilter

现在,让我们将自定义类注册到 dropwizard 安全框架中。

  1. package com.howtodoinjava.rest;
  2. import io.dropwizard.Application;
  3. import io.dropwizard.Configuration;
  4. import io.dropwizard.auth.AuthDynamicFeature;
  5. import io.dropwizard.auth.AuthValueFactoryProvider;
  6. import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
  7. import io.dropwizard.client.JerseyClientBuilder;
  8. import io.dropwizard.setup.Bootstrap;
  9. import io.dropwizard.setup.Environment;
  10. import javax.ws.rs.client.Client;
  11. import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
  12. import com.howtodoinjava.rest.auth.AppAuthorizer;
  13. import com.howtodoinjava.rest.auth.AppBasicAuthenticator;
  14. import com.howtodoinjava.rest.auth.User;
  15. import com.howtodoinjava.rest.controller.EmployeeRESTController;
  16. import com.howtodoinjava.rest.controller.RESTClientController;
  17. import com.howtodoinjava.rest.healthcheck.AppHealthCheck;
  18. import com.howtodoinjava.rest.healthcheck.HealthCheckController;
  19. public class App extends Application<Configuration> {
  20. @Override
  21. public void initialize(Bootstrap<Configuration> b) {
  22. }
  23. @Override
  24. public void run(Configuration c, Environment e) throws Exception {
  25. e.jersey().register(new EmployeeRESTController(e.getValidator()));
  26. final Client client = new JerseyClientBuilder(e).build("DemoRESTClient");
  27. e.jersey().register(new RESTClientController(client));
  28. // Application health check
  29. e.healthChecks().register("APIHealthCheck", new AppHealthCheck(client));
  30. // Run multiple health checks
  31. e.jersey().register(new HealthCheckController(e.healthChecks()));
  32. //****** Dropwizard security - custom classes ***********/
  33. e.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
  34. .setAuthenticator(new AppBasicAuthenticator())
  35. .setAuthorizer(new AppAuthorizer())
  36. .setRealm("BASIC-AUTH-REALM")
  37. .buildAuthFilter()));
  38. e.jersey().register(RolesAllowedDynamicFeature.class);
  39. e.jersey().register(new AuthValueFactoryProvider.Binder<>(User.class));
  40. }
  41. public static void main(String[] args) throws Exception {
  42. new App().run(args);
  43. }
  44. }

具有@Auth注解的安全 REST API

添加@Auth注解将在将其作为参数的任何 API 上触发认证过滤器。

1)用户必须经过验证。 允许所有用户使用 API。

  1. @PermitAll
  2. @GET
  3. public Response getEmployees(@Auth User user) {
  4. return Response.ok(EmployeeDB.getEmployees()).build();
  5. }

2)用户必须经过验证。 仅角色为ADMIN的所有用户都可以使用 API。

  1. @RolesAllowed({ "ADMIN" })
  2. @GET
  3. @Path("/{id}")
  4. public Response getEmployeeById(@PathParam("id") Integer id, @Auth User user) {
  5. Employee employee = EmployeeDB.getEmployee(id);
  6. if (employee != null)
  7. return Response.ok(employee).build();
  8. else
  9. return Response.status(Status.NOT_FOUND).build();
  10. }

这样,您可以根据需要在所有 API 中添加各种认证方案。

测试 Dropwizard 基本验证代码

让我们测试一下我们的安全 API。

调用任何安全的 API

Dropwizard – BasicAuth 安全示例 - 图1

基本认证屏幕

http://localhost:8080/employees

Dropwizard – BasicAuth 安全示例 - 图2

经过认证并允许所有角色

http://localhost:8080/employees/1

Dropwizard – BasicAuth 安全示例 - 图3

经过认证并仅允许ADMIN角色

将我的问题放在评论部分。

学习愉快!

源码下载