Dropwizard:BasicAuth
Dropwizard: BasicAuth
使用 Dropwizard Authentication 0.9.0-SNAPSHOT
我想检查数据库用户 (UserDAO) 的凭据。
我得到以下异常
! org.hibernate.HibernateException: No session currently bound to
execution context
如何绑定session到Authenticator?
或者是否有更好的方法来检查数据库用户?
验证者Class
package com.example.helloworld.auth;
import com.example.helloworld.core.User;
import com.example.helloworld.db.UserDAO;
import com.google.common.base.Optional;
import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials;
public class ExampleAuthenticator implements Authenticator<BasicCredentials, User> {
UserDAO userDAO;
public ExampleAuthenticator(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
Optional<User> user;
user = (Optional<User>) this.userDAO.findByEmail(credentials.getUsername());
if ("secret".equals(credentials.getPassword())) {
return Optional.of(new User(credentials.getUsername()));
}
return Optional.absent();
}
}
申请Class
@Override
public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
final UserDAO userDAO = new UserDAO(hibernate.getSessionFactory());
environment.jersey().register(new AuthDynamicFeature(
new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new ExampleAuthenticator(userDAO))
.setAuthorizer(new ExampleAuthorizer())
.setRealm("SUPER SECRET STUFF")
.buildAuthFilter()));
environment.jersey().register(RolesAllowedDynamicFeature.class);
//If you want to use @Auth to inject a custom Principal type into your resource
environment.jersey().register(new AuthValueFactoryProvider.Binder(User.class));
environment.jersey().register(new UserResource(userDAO));
您的 Application
class 中需要这样的代码
environment.jersey().register(AuthFactory.binder(new BasicAuthFactory<>(
new ExampleAuthenticator(userDAO), "AUTHENTICATION", User.class)));
然后您可以在方法的 User
参数上使用 @Auth
标记,任何传入的身份验证凭据都将命中 authenticate
方法,允许您 return正确的 User
对象或 absent
如果凭据不在您的数据库中。
编辑:适用于 Dropwizard v0.8.4
要使 auth 与 0.9+ 一起工作,您需要以下内容。您可以参考这个特定的 changeset 作为示例。
包括依赖项。
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-auth</artifactId>
<version>${dropwizard.version}</version>
</dependency>
注册授权相关的东西。
private void registerAuthRelated(Environment environment) {
UnauthorizedHandler unauthorizedHandler = new UnAuthorizedResourceHandler();
AuthFilter basicAuthFilter = new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new BasicAuthenticator())
.setAuthorizer(new UserAuthorizer())
.setRealm("shire")
.setUnauthorizedHandler(unauthorizedHandler)
.setPrefix("Basic")
.buildAuthFilter();
environment.jersey().register(new AuthDynamicFeature(basicAuthFilter));
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(new AuthValueFactoryProvider.Binder(User.class));
environment.jersey().register(unauthorizedHandler);
}
基本验证器
public class BasicAuthenticator<C, P> implements Authenticator<BasicCredentials, User> {
@Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
//do no authentication yet. Let all users through
return Optional.fromNullable(new User(credentials.getUsername(), credentials.getPassword()));
}
}
UnAuthorizedHandler
public class UnAuthorizedResourceHandler implements UnauthorizedHandler {
@Context
private HttpServletRequest request;
@Override
public Response buildResponse(String prefix, String realm) {
Response.Status unauthorized = Response.Status.UNAUTHORIZED;
return Response.status(unauthorized).type(MediaType.APPLICATION_JSON_TYPE).entity("Can't touch this...").build();
}
@Context
public void setRequest(HttpServletRequest request) {
this.request = request;
}
}
授权人
public class UserAuthorizer<P> implements Authorizer<User>{
/**
* Decides if access is granted for the given principal in the given role.
*
* @param principal a {@link Principal} object, representing a user
* @param role a user role
* @return {@code true}, if the access is granted, {@code false otherwise}
*/
@Override
public boolean authorize(User principal, String role) {
return true;
}
}
终于在你的资源中使用它了
@GET
public Response hello(@Auth User user){
return Response.ok().entity("You got permission!").build();
}
从0.9开始的最新版本,您可以在资源class方法中使用"@Context"注解,如下所示:
@RolesAllowed("EMPLOYEE")
@Path("/emp")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getEmployeeResponse(@Context SecurityContext context) {
SimplePrincipal sp = (SimplePrincipal) context.getUserPrincipal();
return Response.ok("{\"Hello\": \"Mr. " + sp.getUsername() + "\"( Valuable emp )}").build();
}
使用 Dropwizard Authentication 0.9.0-SNAPSHOT
我想检查数据库用户 (UserDAO) 的凭据。
我得到以下异常
! org.hibernate.HibernateException: No session currently bound to execution context
如何绑定session到Authenticator? 或者是否有更好的方法来检查数据库用户?
验证者Class
package com.example.helloworld.auth;
import com.example.helloworld.core.User;
import com.example.helloworld.db.UserDAO;
import com.google.common.base.Optional;
import io.dropwizard.auth.AuthenticationException;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.basic.BasicCredentials;
public class ExampleAuthenticator implements Authenticator<BasicCredentials, User> {
UserDAO userDAO;
public ExampleAuthenticator(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
Optional<User> user;
user = (Optional<User>) this.userDAO.findByEmail(credentials.getUsername());
if ("secret".equals(credentials.getPassword())) {
return Optional.of(new User(credentials.getUsername()));
}
return Optional.absent();
}
}
申请Class
@Override
public void run(HelloWorldConfiguration configuration, Environment environment) throws Exception {
final UserDAO userDAO = new UserDAO(hibernate.getSessionFactory());
environment.jersey().register(new AuthDynamicFeature(
new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new ExampleAuthenticator(userDAO))
.setAuthorizer(new ExampleAuthorizer())
.setRealm("SUPER SECRET STUFF")
.buildAuthFilter()));
environment.jersey().register(RolesAllowedDynamicFeature.class);
//If you want to use @Auth to inject a custom Principal type into your resource
environment.jersey().register(new AuthValueFactoryProvider.Binder(User.class));
environment.jersey().register(new UserResource(userDAO));
您的 Application
class 中需要这样的代码
environment.jersey().register(AuthFactory.binder(new BasicAuthFactory<>(
new ExampleAuthenticator(userDAO), "AUTHENTICATION", User.class)));
然后您可以在方法的 User
参数上使用 @Auth
标记,任何传入的身份验证凭据都将命中 authenticate
方法,允许您 return正确的 User
对象或 absent
如果凭据不在您的数据库中。
编辑:适用于 Dropwizard v0.8.4
要使 auth 与 0.9+ 一起工作,您需要以下内容。您可以参考这个特定的 changeset 作为示例。
包括依赖项。
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-auth</artifactId>
<version>${dropwizard.version}</version>
</dependency>
注册授权相关的东西。
private void registerAuthRelated(Environment environment) {
UnauthorizedHandler unauthorizedHandler = new UnAuthorizedResourceHandler();
AuthFilter basicAuthFilter = new BasicCredentialAuthFilter.Builder<User>()
.setAuthenticator(new BasicAuthenticator())
.setAuthorizer(new UserAuthorizer())
.setRealm("shire")
.setUnauthorizedHandler(unauthorizedHandler)
.setPrefix("Basic")
.buildAuthFilter();
environment.jersey().register(new AuthDynamicFeature(basicAuthFilter));
environment.jersey().register(RolesAllowedDynamicFeature.class);
environment.jersey().register(new AuthValueFactoryProvider.Binder(User.class));
environment.jersey().register(unauthorizedHandler);
}
基本验证器
public class BasicAuthenticator<C, P> implements Authenticator<BasicCredentials, User> {
@Override
public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
//do no authentication yet. Let all users through
return Optional.fromNullable(new User(credentials.getUsername(), credentials.getPassword()));
}
}
UnAuthorizedHandler
public class UnAuthorizedResourceHandler implements UnauthorizedHandler {
@Context
private HttpServletRequest request;
@Override
public Response buildResponse(String prefix, String realm) {
Response.Status unauthorized = Response.Status.UNAUTHORIZED;
return Response.status(unauthorized).type(MediaType.APPLICATION_JSON_TYPE).entity("Can't touch this...").build();
}
@Context
public void setRequest(HttpServletRequest request) {
this.request = request;
}
}
授权人
public class UserAuthorizer<P> implements Authorizer<User>{
/**
* Decides if access is granted for the given principal in the given role.
*
* @param principal a {@link Principal} object, representing a user
* @param role a user role
* @return {@code true}, if the access is granted, {@code false otherwise}
*/
@Override
public boolean authorize(User principal, String role) {
return true;
}
}
终于在你的资源中使用它了
@GET
public Response hello(@Auth User user){
return Response.ok().entity("You got permission!").build();
}
从0.9开始的最新版本,您可以在资源class方法中使用"@Context"注解,如下所示:
@RolesAllowed("EMPLOYEE")
@Path("/emp")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getEmployeeResponse(@Context SecurityContext context) {
SimplePrincipal sp = (SimplePrincipal) context.getUserPrincipal();
return Response.ok("{\"Hello\": \"Mr. " + sp.getUsername() + "\"( Valuable emp )}").build();
}