Question

I am playing with restlet and i want to create a login mechanism that passwords and usernames are store in a MysqlDatabase.

public class zeus extends Application {

    @Override
    public Restlet createInboundRoot() {
        // Δημιουργία του router.
        Router router = new Router(getContext());
        router.attach("/customers", CustomersResource.class);

        ChallengeAuthenticator guard = new ChallengeAuthenticator(getContext(), ChallengeScheme.HTTP_BASIC, "login required");

        UserVerifier verifier = new UserVerifier();
        verifier.verify(identifier, secret); // where do i get the identifier ?
        guard.setVerifier(verifier);

        guard.setNext(router);
        return guard;
    }
}

And my user verifier class

public class UserVerifier extends SecretVerifier {

    @Override
    public boolean verify(String identifier, char[] secret) {
    System.out.println(identifier);
    System.out.println(secret);
    //TODO compare with the Database
    return true;
    }


}

i cannot find how to get the identifier.

Was it helpful?

Solution

If I correctly understand your question, your problem is how to interact with the database from your Restlet verifier and how make work together within your Restlet application.

The best approach is to define a DAO that implement your database interaction logic. Something like that:

public class SecurityDao {
    private DataSource dataSource;

    public SecurityDao() {
        // Intialize your datasource using DBCP or C3P0
        dataSource = new com.mchange.v2.c3p0.ComboPooledDataSource();
        dataSource.setDriverClass(MyDriverClass.class);
        dataSource.setJdbcUrl("jdbc:mysql://locahost/mydb");
        dataSource.setUser("username");
        dataSource.setPassword("pwd");

        // Don't forget to clean the pool when Restlet application stop
        // with ComboPooledDataSource#close method
    }

    public boolean hasUserPassword(String user, String password) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            // Some SQL request like that
            ps = conn.prepareStatement("select * from <MYTABLE> where USER = ? and PASSWORD = ?");
            ps.setString(1, user);
            ps.setString(2, password);
            rs = ps.executeQuery();
            return rs.next();
        } catch(Exception ex) {
            (...)
        } finally {
            // close rs
            // close ps
            // close conn
        }
    }
}

Now we have the DAO implemented, we will instantiate it from the Restlet application class and set it within your verifier:

public class zeus extends Application {
    private SecurityDao securityDao;

    public zeus() {
        securityDao = new SecurityDao();
    }

    @Override
    public Restlet createInboundRoot() {
        (...)

        UserVerifier verifier = new UserVerifier();
        verifier.setSecurityDao(securityDao);

        (...)
        return guard;
    }
}

You need now to adapt a bit your verifier as described below:

public class UserVerifier extends SecretVerifier {
    private SecurityDao securityDao;
    public void setSecurityDao(SecurityDao securityDao) {
        this.securityDao = securityDao;
    }

    public boolean verify(String identifier, char[] secret) {
        System.out.println(identifier);
        System.out.println(secret);
        return securityDao.hasUserPassword(identifier, new String(secret));
        return true;
    }
}

In fact, the method createInboundRoot of the Restlet application initializes the routing. This is done once when the application starts ie when the first request is done. Then when an HTTP request will be received, Restlet automatically calls the verifier with security hints present in this request. You haven't to explicitly call the verify method of the verifier, the Restlet framework will do that...

Hope it helps you, Thierry

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top