2015-09-19 11 views
6

Utilizzando Dropwizard Authentication 0.9.0-SNAPSHOTDropwizard: BasicAuth

voglio controllare le credenziali contro utente del database (UserDAO).

ottengo la seguente eccezione

! org.hibernate.HibernateException: No sessione al momento legato contesto esecuzione

Come associare la sessione per l'Authenticator? O ci sono modi migliori per controllare l'utente del database?

L'Authenticator Classe

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

La classe di applicazione

@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

prega di notare che questa domanda si riferisce a RC 0.9.0- RC4. –

+0

colpendo lo stesso problema con 0.9.1.Final – harshil

risposta

5

Per arrivare autenticazione a lavorare con 0.9+ è necessario quanto segue. È possibile fare riferimento a questo particolare changeset come esempio.

Includere la dipendenza.

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

Registro roba correlata.

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

} 

Un autenticatore base

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

Infine usarlo nella vostra risorsa

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

Si sta andando ad avere bisogno di codice nella classe Application che assomiglia a questo

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

Poi si può usare il @Auth t ag su un parametro User per un metodo e tutte le credenziali di autenticazione in entrata colpiranno il metodo authenticate, consentendo di restituire l'oggetto User corretto o absent se le credenziali non sono nel database.

EDIT: Lavori per la Dropwizard v0.8.4

+0

Grazie Rohan, ma questo non funziona con Dropwizard 0.9.0-rc4. –

+0

@DanielOzean Ah, capisco. Questo dovrebbe funzionare su Dropwizard 0.8.4, che è l'ultima versione ufficiale. Potresti non voler sviluppare con 0.9.0 fino a quando non viene rilasciato ufficialmente. – Rohan

+0

@ Hai ragione. Segnerò questo come risolto. –

1

sulle più recenti versioni a partire dalla 0.9 in poi, è possibile utilizzare "@Context" annotazione nei metodi della classe di risorse come illustrato di seguito:

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

    } 
Problemi correlati