By looking at UserServlet (which applies to the USER role), we can see the authentication step:
securityContext.authenticate(
request, response, withParams().credential(new
CallerOnlyCredential(Roles.ADMIN)));
For example, we've used the role name as a username because if we look at the AuthenticationMechanism class (which is implementing HttpAuthenticationMechanism), we can see it doing all the hard work of authenticating and assigning the right role to the user:
Credential credential =
httpMessageContext.getAuthParameters()
.getCredential();
if (!(credential instanceof CallerOnlyCredential)) {
throw new IllegalStateException("Invalid mechanism");
}
CallerOnlyCredential callerOnlyCredential =
(CallerOnlyCredential)
credential;
if (null == callerOnlyCredential.getCaller()) {
throw new AuthenticationException();
} else switch (callerOnlyCredential.getCaller()) {
case Roles.ADMIN:
return httpMessageContext.notifyContainerAboutLogin
(callerOnlyCredential.getCaller(), new HashSet<>
(asList(Roles.ADMIN)));
case Roles.USER:
return httpMessageContext.notifyContainerAboutLogin
(callerOnlyCredential.getCaller(), new HashSet<>
(asList(Roles.USER)));
default:
throw new AuthenticationException();
}
Let's go back to UserServlet. Now that the user has been assigned the correct role, it is just a matter of what they can and cannot do. This can be seen in the following code:
userExecutor.run(() -> {
try {
userActivity.adminOperation();
response.getWriter().write("adminOperation
executed: true\n");
} catch (Exception e) {
response.getWriter().write("adminOperation
executed: false\n");
}
try {
userActivity.userOperation();
response.getWriter().write("userOperation
executed: true\n");
} catch (Exception e) {
response.getWriter().write("userOperation
executed: false\n");
}
});
We also need to try the tasks that everyone and no one can perform:
try {
userActivity.everyoneCanDo();
response.getWriter().write("everyoneCanDo
executed: true\n");
} catch (Exception e) {
response.getWriter().write("everyoneCanDo
executed: false\n");
}
try {
userActivity.noneCanDo();
response.getWriter().write("noneCanDo
executed: true\n");
} catch (Exception e) {
response.getWriter().write("noneCanDo
executed: false\n");
}
The AdminServlet class goes through exactly the same steps using an AdminExecutor environment, so we will omit it for the sake of space.
To try this code out for yourself, just run it on a Java EE 8-compatible server using the following URLs:
- http://localhost:8080/ch05-declarative/AdminServlet
- http://localhost:8080/ch05-declarative/UserServlet
The result for AdminServlet will be as follows:
Role "admin" access: true
Role "user" access: false
adminOperation executed: true
userOperation executed: false
everyoneCanDo executed: true
noneCanDo executed: false