DropWizard Auth通过示例

我试图了解DropWizard中身份验证和授权的工作方式。我已经阅读了他们的身份验证指南以及GitHub上的dropwizard-

security项目,但是觉得我仍然缺少一些重要的概念。

public class SimpleCredential {

private String password;

public SimpleCredential(String password) {

super();

this.password = password;

}

}

public class SimplePrincipal {

pivate String username;

public SimplePrincipal(String username) {

super();

this.username = username;

}

}

public class SimpleAuthenticator implements Authenticator<SimpleCredential, SimplePrincipal> {

@Override

public Optional<SimplePrincipal> authenticate(SimpleCredential credential) throws AuthenticationException {

if(!"12345".equals(credential.getPassword())) {

throw new AuthenticationException("Sign in failed.");

}

Optional.fromNullable(new SimplePrincipal("simple_user"));

}

}

然后在我的Application子类中:

@Override

public void run(BackendConfiguration configuration, Environment environment) throws Exception {

environment.jersey().register(new BasicAuthProvider<SimplePrincipal>(new SimpleAuthenticator(), "SUPER SECRET STUFF"));

}

然后在资源方法中:

@GET

@Path("address/{address_id}")

@Override

public Address getAddress(@Auth @PathParam("address_id") Long id) {

addressDao.getAddressById(id);

}

我觉得我有这个半正确配置为基本身份验证,但不理解的角色SimpleCredentialSimplePrincipal发挥。特别:

  1. 如何从Jersey / JAX-RS客户端设置基本身份验证用户名/密码?
  2. 什么作用SimpleCredential,并SimplePrincipal与基本身份验证戏?我是否需要向它们或其他类添加任何内容以使基本身份验证工作,使得唯一有效的用户名是simple_user,唯一有效的密码是12345
  3. 如何通过强制执行访问/授权/角色SimplePrincipal?还是Web服务不存在授权的概念?

回答:

回答:

基本身份验证协议规定客户端请求应具有以下形式的标头:

Authorization: Basic Base64Encoded(username:password)

其中Base64Encoded(username:password)是的实际Base64编码的字符串username:password。例如,如果我的用户名和密码为peeskillet:pass,则标题应发送为

Authorization: Basic cGVlc2tpbGxldDpwYXNz

话虽这么说,Jersey

Client(假设1.x)有一个HTTPBasicAuthFilter,这是一个客户端过滤器,它将为我们处理编码部分。因此客户端请求可能看起来像

Client client = Client.create();

WebResource resource = client.resource(BASE_URI);

client.addFilter(new HTTPBasicAuthFilter("peeskillet", "pass"));

String response = resource.get(String.class);

这就是我们需要使用授权标头进行简单的GET请求了。

回答:

对于基本身份验证,实际上将要求我们使用BasicCredentials,而不是我们自己的凭据。基本上,请求将通过BasicAuthProvider。提供者将解析Authorization标头,并BasicCredentials根据解析的用户名和密码创建一个对象。处理完成后,BasicCredentials将会传递给我们SimpleAuthenticator的。我们使用这些凭据对用户进行身份验证。

基本上就是我们用来 授权

客户端的内容。在身份验证过程中,我们可以构建一个主体,该主体将在以后用于授权(请参阅问题3)。所以一个例子可能看起来像

import com.google.common.base.Optional;

import io.dropwizard.auth.AuthenticationException;

import io.dropwizard.auth.Authenticator;

import io.dropwizard.auth.basic.BasicCredentials;

public class SimpleAuthenticator implements Authenticator<BasicCredentials,

SimplePrincipal> {

@Override

public Optional<SimplePrincipal> authenticate(BasicCredentials credentials)

throws AuthenticationException {

// Note: this is horrible authentication. Normally we'd use some

// service to identify the password from the user name.

if (!"pass".equals(credentials.getPassword())) {

throw new AuthenticationException("Boo Hooo!");

}

// from some user service get the roles for this user

// I am explicitly setting it just for simplicity

SimplePrincipal prince = new SimplePrincipal(credentials.getUsername());

prince.getRoles().add(Roles.ADMIN);

return Optional.fromNullable(prince);

}

}

我对SimplePrincipal类进行了一些更改,并创建了一个简单的Roles类。

public class SimplePrincipal {

private String username;

private List<String> roles = new ArrayList<>();

public SimplePrincipal(String username) {

this.username = username;

}

public List<String> getRoles() {

return roles;

}

public boolean isUserInRole(String roleToCheck) {

return roles.contains(roleToCheck);

}

public String getUsername() {

return username;

}

}

public class Roles {

public static final String USER = "USER";

public static final String ADMIN = "ADMIN";

public static final String EMPLOYEE = "EMPLOYEE";

}

回答:

有些人可能更喜欢为授权使用额外的过滤器层,但Dropwizard似乎认为授权应该在资源类中进行(我忘记了阅读的确切位置,但我 认为

他们的观点是可测试性)。SimplePrincial我们在中创建的会发生什么SimpleAuthenticator,就是可以通过使用@Auth批注将其注入到我们的资源方法中。我们可以使用SimplePrincipal进行授权。就像是

import dropwizard.sample.helloworld.security.Roles;

import dropwizard.sample.helloworld.security.SimplePrincipal;

import io.dropwizard.auth.Auth;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.WebApplicationException;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

@Path("/simple")

public class SimpleResource {

@GET

@Produces(MediaType.APPLICATION_JSON)

public Response getResponse(@Auth SimplePrincipal principal) {

if (!principal.isUserInRole(Roles.ADMIN)) {

throw new WebApplicationException(Response.Status.FORBIDDEN);

}

return Response.ok(

"{\"Hello\": \"" + principal.getUsername() + "\"}").build();

}

}


因此,使用此配置将它们放在一起

environment.jersey().register(new BasicAuthProvider<SimplePrincipal>(

new SimpleAuthenticator(),

"Basic Example Realm")

);

以及我之前发布的客户凭证,当我们发出请求时,我们应该得到一个返回

{"Hello": "peeskillet"}


还应该提到的是,仅基本身份验证是不安全的,建议通过SSL完成


  • 带DropWizard的SSL


回答:

几件事:

  • 对于Dropwizard 0.8.x,基本身份验证的配置有所更改。你可以 看到 。一个简单的例子是

        SimpleAuthenticator auth = new SimpleAuthenticator();

env.jersey().register(AuthFactory.binder(

new BasicAuthFactory<>(auth,"Example Realm",SimplePrincipal.class)));

  • 请参阅上面的链接以获取推荐的用法 AuthenticationException

以上是 DropWizard Auth通过示例 的全部内容, 来源链接: utcz.com/qa/410211.html

回到顶部