Reputation: 3657
Design pattern help:
I have a dropwizard application that implements JWT for authentication. I have this working in the most basic form.
I have a User class which has all sorts of details about a user (email, name, settings etc)
However I've been advised that when I authenticate the user I should be returning a Principal rather than the actual user. Here is my method that does this:
@Override
public Optional<Principal> authenticate(JsonWebToken token) throws AuthenticationException {
final User user = userCollection.findOneById(token.claim().subject());
Principal principal = new Principal() {
@Override
public String getName() {
return user.getUsername();
}
};
return Optional.of(principal);
}
I have the users stored in a mongoDB collection, so using the ID from the token I can retrieve that specific user and assign that users name to a new principal object and return that principal.
This means in my endpoints that require authentication, I can use properties from that Principal for example:
@POST
@Path("project-create")
public Response setProject(@Auth Principal principal, @Valid Project project) {
[...]
project.setAuthorName(principal.getName());
[...]
}
This is all working, but what if I wanted to access other properties of the user which don't exist on the Principal?
Should I be using the name
value of the principal to lookup the user in the database and retrieve that user each time I want to use one of the users properties?
Is there a massive flaw in what I've done? I don't have much experience on this front and find it hard to find real world examples around this.
Would appreciate some guidance around what sort of pattern/workflow I should be following.
Upvotes: 2
Views: 2355
Reputation: 209052
The Authenticator
generic type is Athenticator<C, P extends Principal>
, so you can make your User
implement Principal
and make your Authenticator
something like
public class JWTAuthenicator extends Authenticator<JsonWebToken, User> {
@Override
public Optional<User> authenticate(JsonWebToken token) {}
}
Then build the JWTAuthFilter
with the User
generic type argument
new JWTAuthFilter.Builder<User>()
.setAuthenticator(new JWTAuthenticator())
.setEverythingElse(...)
.buildAuthFilter();
Upvotes: 4