Question

Using a Jersey service, what would be the most elegant method to authenticate a user with more than just username and password? say, a Business Id, and username as the Principals, and password as the only Credential.

I have a postgres DB with a users table, the same username string can exist for multiple Business entities. (A unique constraint belongs to two columns, Business id and username together).

I Use Basic authentication, having the client send an additional HTTP Header for the Business id. how do I go on from here?

Now, Regarding Authorization, how would I set up Roles and Permissions, if roles are created specifically for each business entity (each business can define it's own roles and connect it to permissions.)? Permissions are static.

does apache shiro (or any other pluggable security extension) offer a solution in this case?

Thanks.

Was it helpful?

Solution

You might consider.

  1. Implement auth logic in the good old servlet filter. JAX-RS application is just normal WWW aplication, so Filters fits well as a simple authorization mechanism.

  2. JAX-RS interceptors (PreProcessInterceptor) where you can implement your auth logic as you need (calling database, etc.) This is "more idiomatic" while working with JAX-RS.

  3. Use Spring Security. This is a good option if you are ready to learn a little it of Spring Framework. Spring Security provides full featured authentication and access control mechanism, so you can implement whatever you need. Note that the rest of application does not neeed to use Spring.

  4. You might also use CDI decorators (example) to implement auth logic, but that would be sort of exotic given still low CDI adoption.

Personaly I would go with 1. or 2, for simple cases and 3 for something more advanced.

OTHER TIPS

(Old question! a response for new users) As you tagged SHIRO in your question, you can just add your own logic by extanding
org.apache.shiro.realm.jdbc.JdbcRealm
and @Override:
getRoleNamesForUser(...) , getPermissions(..), doGetAuthenticationInfo(..)
This is an example:

@Override
protected Set<String> getRoleNamesForUser(Connection conn, String username) throws SQLException {
    Set<String> roleNames = new LinkedHashSet<>();

    Collection<UserRole> roles = /* Get roles from your DB, this example use  JPA entity, **but you put here any logic you want**...*/
    for(UserRole userRole:roles){
        roleNames.add(userRole.getRole().getName());
    }
    return roleNames; // return roles so Shiro is 'aware' of roles to add them to current user
}

*note that same logic applies for other methods that you override.
** You don't need 2 http calls to log the user, you can just user Shiro programatic auth.

here is a Complete example with Shiro annotation enabled..and more

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