authenticationdropwizardsecurity-context

Using Dropwizard Authentication manual


I'm currently using http://www.dropwizard.io/1.1.0/docs/manual/auth.html# Dropwizard-Authentication in my Application. But i like to do the authentication "manualy" which means from a specific login/logout API call on a not authenticated REST interface.

Is there any possibility to forward an REST Call to the Authentication?

@POST
@Path("login")
@Consumes(MediaType.APPLICATION_JSON)
@Timed
@UnitOfWork
public Optional<LoginResponse> login(LoginRequest request) {
    // TODO forward login request to authentication
    return null;
}

Thx in advance


Solution

  • Thx for helping me. I found a solution like that:

    Adding an Authenticator to the REST Client

        client = ClientBuilder.newClient();
        authenticator = new Authenticator();
        client.register(authenticator);
    

    Setup the Authenticator on Login-Successfull

        final UserAPIResponse response = create(request, UserAPI.PATH_ATTRIBUTE_DEFINITION_LOGIN);
        if (response == null || response.isFailed()) {
            connector.setupAuthenticator(null, null);
        } else {
            connector.setupAuthenticator(request.getUsername(), request.getPassword());
        }
    

    And here is the Authenticator

    class Authenticator implements ClientRequestFilter {
    
    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        final MultivaluedMap<String, Object> headers = requestContext.getHeaders();
        final String basicAuthentication = getBasicAuthentication();
        if (basicAuthentication == null) return;
        headers.add("Authorization", basicAuthentication);
    
    }
    
    void setup(String username, String password) {
        this.user = username;
        this.password = password;
    }
    
    private String getBasicAuthentication() {
        if (user == null || password == null) return null;
        final String token = this.user + ":" + this.password;
        try {
            return "BASIC " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
        } catch (final UnsupportedEncodingException ex) {
            throw new IllegalStateException("Cannot encode with UTF-8", ex);
        }
    }
    
    private String password;
    
    private String user;
    

    }

    on the server side i have an Authenticator

    public class UserAuthenticator implements Authenticator<BasicCredentials, User> {
    
    UserAuthenticator(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
    
    @UnitOfWork
    @Override
    public Optional<User> authenticate(BasicCredentials credentials) throws AuthenticationException {
        final String username = credentials.getUsername();
        final Optional<DbUser> result = userDAO.getByName(username);
        if (!result.isPresent()) return Optional.empty();
    
        final DbUser user = result.get();
        final String password = credentials.getPassword();
        if (!StringUtils.equals(password, user.getPassword())) return Optional.empty();
    
        if (!user.isOnline()) return Optional.empty();
        user.handleAction();
        userDAO.save(user);
    
        return Optional.of(UserMgr.convert(user));
    }
    
    private final UserDAO userDAO;
    

    }

    And to get em working correctly:

    SessionDao dao = new SessionDao(hibernateBundle.getSessionFactory());
    ExampleAuthenticator exampleAuthenticator = new      UnitOfWorkAwareProxyFactory(hibernateBundle)
               .create(ExampleAuthenticator.class, SessionDao.class, dao);
    

    So finally there is one REST-Call to login the User and the authentication is done on the result by the client automatically.