- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚刚开始使用 Dropwizard 0.4.0,我想要一些有关 HMAC 身份验证的帮助。有人有什么建议吗?
先感谢您。
最佳答案
目前 Dropwizard 不支持开箱即用的 HMAC 身份验证,因此您必须编写自己的身份验证器。 HMAC 身份验证的典型选择是使用 HTTP 授权 header 。以下代码要求此 header 采用以下格式:
Authorization: <algorithm> <apiKey> <digest>
Authorization: HmacSHA1 abcd-efgh-1234 sdafkljlkansdaflk2354jlkj5345345dflkmsdf
dropwizard-auth
模块中的 BasicAuthenticator 代码复制到您自己的代码中,并使用以下内容对其进行修改:
import com.google.common.base.Optional;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
import com.yammer.dropwizard.auth.AuthenticationException;
import com.yammer.dropwizard.auth.Authenticator;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
class HmacAuthInjectable<T> extends AbstractHttpContextInjectable<T> {
private static final String PREFIX = "HmacSHA1";
private static final String HEADER_VALUE = PREFIX + " realm=\"%s\"";
private final Authenticator<HmacCredentials, T> authenticator;
private final String realm;
private final boolean required;
HmacAuthInjectable(Authenticator<HmacCredentials, T> authenticator, String realm, boolean required) {
this.authenticator = authenticator;
this.realm = realm;
this.required = required;
}
public Authenticator<HmacCredentials, T> getAuthenticator() {
return authenticator;
}
public String getRealm() {
return realm;
}
public boolean isRequired() {
return required;
}
@Override
public T getValue(HttpContext c) {
try {
final String header = c.getRequest().getHeaderValue(HttpHeaders.AUTHORIZATION);
if (header != null) {
final String[] authTokens = header.split(" ");
if (authTokens.length != 3) {
// Malformed
HmacAuthProvider.LOG.debug("Error decoding credentials (length is {})", authTokens.length);
throw new WebApplicationException(Response.Status.BAD_REQUEST);
}
final String algorithm = authTokens[0];
final String apiKey = authTokens[1];
final String signature = authTokens[2];
final String contents;
// Determine which part of the request will be used for the content
final String method = c.getRequest().getMethod().toUpperCase();
if ("GET".equals(method) ||
"HEAD".equals(method) ||
"DELETE".equals(method)) {
// No entity so use the URI
contents = c.getRequest().getRequestUri().toString();
} else {
// Potentially have an entity (even in OPTIONS) so use that
contents = c.getRequest().getEntity(String.class);
}
final HmacCredentials credentials = new HmacCredentials(algorithm, apiKey, signature, contents);
final Optional<T> result = authenticator.authenticate(credentials);
if (result.isPresent()) {
return result.get();
}
}
} catch (IllegalArgumentException e) {
HmacAuthProvider.LOG.debug(e, "Error decoding credentials");
} catch (AuthenticationException e) {
HmacAuthProvider.LOG.warn(e, "Error authenticating credentials");
throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
}
if (required) {
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.AUTHORIZATION,
String.format(HEADER_VALUE, realm))
.entity("Credentials are required to access this resource.")
.type(MediaType.TEXT_PLAIN_TYPE)
.build());
}
return null;
}
}
ResourceTest
子类中。不幸的是,Dropwizard 在 v0.4.0 中没有为身份验证提供程序提供一个好的入口点,因此您可能需要引入自己的基类,类似于以下内容:
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.test.framework.AppDescriptor;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.LowLevelAppDescriptor;
import com.xeiam.xchange.utils.CryptoUtils;
import com.yammer.dropwizard.bundles.JavaBundle;
import com.yammer.dropwizard.jersey.DropwizardResourceConfig;
import com.yammer.dropwizard.jersey.JacksonMessageBodyProvider;
import com.yammer.dropwizard.json.Json;
import org.codehaus.jackson.map.Module;
import org.junit.After;
import org.junit.Before;
import org.multibit.mbm.auth.hmac.HmacAuthProvider;
import org.multibit.mbm.auth.hmac.HmacAuthenticator;
import org.multibit.mbm.persistence.dao.UserDao;
import org.multibit.mbm.persistence.dto.User;
import org.multibit.mbm.persistence.dto.UserBuilder;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Set;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* A base test class for testing Dropwizard resources.
*/
public abstract class BaseResourceTest {
private final Set<Object> singletons = Sets.newHashSet();
private final Set<Object> providers = Sets.newHashSet();
private final List<Module> modules = Lists.newArrayList();
private JerseyTest test;
protected abstract void setUpResources() throws Exception;
protected void addResource(Object resource) {
singletons.add(resource);
}
public void addProvider(Object provider) {
providers.add(provider);
}
protected void addJacksonModule(Module module) {
modules.add(module);
}
protected Json getJson() {
return new Json();
}
protected Client client() {
return test.client();
}
@Before
public void setUpJersey() throws Exception {
setUpResources();
this.test = new JerseyTest() {
@Override
protected AppDescriptor configure() {
final DropwizardResourceConfig config = new DropwizardResourceConfig();
for (Object provider : JavaBundle.DEFAULT_PROVIDERS) { // sorry, Scala folks
config.getSingletons().add(provider);
}
for (Object provider : providers) {
config.getSingletons().add(provider);
}
Json json = getJson();
for (Module module : modules) {
json.registerModule(module);
}
config.getSingletons().add(new JacksonMessageBodyProvider(json));
config.getSingletons().addAll(singletons);
return new LowLevelAppDescriptor.Builder(config).build();
}
};
test.setUp();
}
@After
public void tearDownJersey() throws Exception {
if (test != null) {
test.tearDown();
}
}
/**
* @param contents The content to sign with the default HMAC process (POST body, GET resource path)
* @return
*/
protected String buildHmacAuthorization(String contents, String apiKey, String secretKey) throws UnsupportedEncodingException, GeneralSecurityException {
return String.format("HmacSHA1 %s %s",apiKey, CryptoUtils.computeSignature("HmacSHA1", contents, secretKey));
}
protected void setUpAuthenticator() {
User user = UserBuilder
.getInstance()
.setUUID("abc123")
.setSecretKey("def456")
.build();
//
UserDao userDao = mock(UserDao.class);
when(userDao.getUserByUUID("abc123")).thenReturn(user);
HmacAuthenticator authenticator = new HmacAuthenticator();
authenticator.setUserDao(userDao);
addProvider(new HmacAuthProvider<User>(authenticator, "REST"));
}
}
import com.google.common.base.Optional;
import com.yammer.dropwizard.auth.Auth;
import com.yammer.metrics.annotation.Timed;
import org.multibit.mbm.core.Saying;
import org.multibit.mbm.persistence.dto.User;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.concurrent.atomic.AtomicLong;
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
private final String template;
private final String defaultName;
private final AtomicLong counter;
public HelloWorldResource(String template, String defaultName) {
this.template = template;
this.defaultName = defaultName;
this.counter = new AtomicLong();
}
@GET
@Timed
@Path("/hello-world")
public Saying sayHello(@QueryParam("name") Optional<String> name) {
return new Saying(counter.incrementAndGet(),
String.format(template, name.or(defaultName)));
}
@GET
@Timed
@Path("/secret")
public Saying saySecuredHello(@Auth User user) {
return new Saying(counter.incrementAndGet(),
"You cracked the code!");
}
}
import org.junit.Test;
import org.multibit.mbm.core.Saying;
import org.multibit.mbm.test.BaseResourceTest;
import javax.ws.rs.core.HttpHeaders;
import static org.junit.Assert.assertEquals;
public class HelloWorldResourceTest extends BaseResourceTest {
@Override
protected void setUpResources() {
addResource(new HelloWorldResource("Hello, %s!","Stranger"));
setUpAuthenticator();
}
@Test
public void simpleResourceTest() throws Exception {
Saying expectedSaying = new Saying(1,"Hello, Stranger!");
Saying actualSaying = client()
.resource("/hello-world")
.get(Saying.class);
assertEquals("GET hello-world returns a default",expectedSaying.getContent(),actualSaying.getContent());
}
@Test
public void hmacResourceTest() throws Exception {
String authorization = buildHmacAuthorization("/secret", "abc123", "def456");
Saying actual = client()
.resource("/secret")
.header(HttpHeaders.AUTHORIZATION, authorization)
.get(Saying.class);
assertEquals("GET secret returns unauthorized","You cracked the code!", actual.getContent());
}
}
关于dropwizard - 如何使用 Dropwizard 测试 HMAC 身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10783060/
我在我的机器上集成了 dropwizards。 我公开了它们,但我正在寻找它们的含义的信息。 例如,我如何获得每秒的请求数?任何此类信息都可以在任何地方获得,因为我无法在官方网站上找到它。 谢谢。 最
我想知道“Counter”和“Meter”类维护的计数之间是否有区别?我了解仪表也测量费率,但我很好奇是否有一个计数器和一个仪表同时更新(计数器增加),我认为两个数字会相同。我这个假设错了吗? 最佳答
我在我的机器上集成了 dropwizards。 我公开了它们,但我正在寻找它们的含义的信息。 例如,我如何获得每秒的请求数?任何此类信息都可以在任何地方获得,因为我无法在官方网站上找到它。 谢谢。 最
为什么 dropwizard 有两个不同的 groupId。io.dropwizard和com.yammer.dropwizard 当你会在 git pom 文件中看到。它有 io.dropwizar
我的 dropwizard 日志仅将所有内容输出到控制台,并输出所有级别的日志记录。我想在开发输出到控制台期间为我自己的东西记录一些日志,但过滤掉噪音。我已经坚持了一段时间,自从我升级到 dropwi
我正在使用 dropwizard 版本 0.7.1。它被配置为使用“随机”(临时?)端口(server.applicationConnectors.port=0)。我想在启动后获得真正在使用的端口,但
关闭。这个问题不符合 Stack Overflow guidelines 。它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 Stack Overflow 的 on-topic。 2年前关闭。
如何对Dropwizard管理门户进行身份验证,以限制普通用户访问它?请帮忙 最佳答案 在您的配置中,您可以在 http 下设置 adminUsername 和 adminPassword,如下所示:
我无法在 Dropwizard 应用程序的 run() 方法中注册多个资源。当我这样做时,我收到以下异常: Exception in thread "main" MultiException[java
我正在尝试从 dropwizard 应用程序构建 war 并进行部署。 我可以成功运行 jar 并访问我的休息服务。 有没有人从 dropwizard 应用程序创建并成功部署了一场 war ? 什么是
与 ObjectMapper ( com.fasterxml.jackson.databind ) 可以指定它应该忽略未知属性。这可以通过添加 @JsonIgnoreProperties(ignore
当我使用 Dropwizard 开发微服务时,我试图在 Dropwizard 的一个正在运行的实例/应用程序上拥有许多资源与在许多实例上拥有许多资源之间找到平衡。 例如 - 我有一个项目 A,有 3
我刚刚开始使用 Dropwizard 0.4.0,我想要一些有关 HMAC 身份验证的帮助。有人有什么建议吗? 先感谢您。 最佳答案 目前 Dropwizard 不支持开箱即用的 HMAC 身份验证,
我有一个 dropwizard 应用程序,它发出 yammer 指标,可以通过像 http://localhost:8081/admin/metrics 这样的 URL 进行监控。它以jsons的形式
我正在尝试为 Dropwizard 创建一个计划作业,该作业每分钟运行一次并查询数据库中的值。 为此,我需要在 initialize() 中注册一些 DAO 和服务。阶段,像这样: @Override
您如何将 dropwizard jdbi 2.78 升级到 jdbi 版本 3,因为我想使用其中包含的连接功能。 最佳答案 项目成员在这里。 我们将在 v3 最终版本之前发布更完整的迁移指南。与此同时
我在 Dropwizard 0.8 中使用 Basic Auth 并且我需要访问我的 SimpleAuthenticator 类中的请求上下文,而不是基本凭据。 也许我需要我自己的 AuthFacto
使用 Dropwizard 0.6.2 很容易做到这一点,但随着迁移到 0.7.x,它变得更加困难。我可以让它工作,但不是以完全合适的方式。我希望我的 RESTful API 在“/api/*”点可用
我是 dropwizard 的新手。我正在使用 0.8.5 版的 dropwizard。我有一个 dropwizard REST 服务,它在调用成功时返回 JSON,在调用不成功时返回 HTTL,例如
我是 dropwizard 的新手。我正在使用 0.8.5 版的 dropwizard。我有一个 dropwizard REST 服务,它在调用成功时返回 JSON,在调用不成功时返回 HTTL,例如
我是一名优秀的程序员,十分优秀!