2015-09-19 12 views
6

Mit Dropwizard Authentication 0.9.0-SNAPSHOTDropwizard: BasicAuth

ich die Anmeldeinformationen gegen Datenbankbenutzer (UserDAO) überprüfen möchten.

Ich erhalte die folgende Ausnahme

! org.hibernate.HibernateException: keine Sitzung zur Zeit gebunden Ausführungskontext

Wie die Sitzung mit dem Authenticator zu binden? Oder gibt es bessere Möglichkeiten, den Datenbankbenutzer zu überprüfen?

Der Authenticator Klasse

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(); 
    } 
} 

Die Anwendungsklasse

@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)); 
+0

Bitte beachten Sie, dass diese Frage 0.9.0- rc bezieht sich RC4. –

+0

schlägt das gleiche Problem mit 0.9.1.Final – harshil

Antwort

5

Auth, um zu arbeiten 0.9+ Sie folgendes benötigen. Sie können als Beispiel auf dieses spezielle changeset verweisen.

Die Abhängigkeit einschließen.

<dependency> 
    <groupId>io.dropwizard</groupId> 
    <artifactId>dropwizard-auth</artifactId> 
    <version>${dropwizard.version}</version> 
</dependency> 

Registrieren Auth verwandte Sachen.

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); 

} 

Eine grundlegende Authenticator

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; 
    } 
} 

Authorizer

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; 
    } 
} 

es schließlich in Ihrer Ressource verwenden

@GET 
public Response hello(@Auth User user){ 
    return Response.ok().entity("You got permission!").build(); 
} 
3

Sie werden Code in Ihre Application Klasse müssen, die wie diese Sie

environment.jersey().register(AuthFactory.binder(new BasicAuthFactory<>( new ExampleAuthenticator(userDAO), "AUTHENTICATION", User.class)));

sieht dann kann die @Auth t verwenden ag auf einem User Parameter für eine Methode und alle eingehenden Authentifizierung Anmeldeinformationen werden die authenticate Methode, so dass Sie die richtige User Objekt oder absent zurückgegeben, wenn die Anmeldeinformationen nicht in Ihrer Datenbank sind.

EDIT: Werke für Dropwizard v0.8.4

+0

Danke Rohan, aber das funktioniert nicht mit Dropwizard 0.9.0-rc4. –

+0

@DanielOzean Ah, ich verstehe. Dies sollte mit Dropwizard 0.8.4, der neuesten offiziellen Version, funktionieren. Sie möchten vielleicht nicht mit 0.9.0 entwickeln, bis es offiziell veröffentlicht wird. – Rohan

+0

@You Recht. Ich werde das als gelöst markieren. –

1

auf den neuesten Versionen von 0.9 beginnend weiter, können Sie „@Context“ Annotation in Ressourcenklassenmethoden verwenden, wie unten dargestellt:

@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(); 

    }