How it works...

Let's split up the code shown earlier, so that we can better understand what's happening.

In the web.xml file, we are creating a security constraint:

    <security-constraint>
...
</security-constraint>

We're defining a resource inside it:

        <web-resource-collection>
<web-resource-name>CH05-Authentication</web-resource-name>
<url-pattern>/authServlet</url-pattern>
</web-resource-collection>

And we're defining an authorization policy. In this case, it's a role:

        <auth-constraint>
<role-name>role1</role-name>
</auth-constraint>

Now we have UserAuthenticationServlet. We should pay attention to this annotation:

@DeclareRoles({"role1", "role2", "role3"})

It defines which roles are part of the context of this particular servlet.

Another important actor in this scene is this one:

    @Inject
private SecurityContext securityContext;

Here, we are asking the server to give us a security context so that we can use it for our purpose. It will make sense in a minute.

Then, if the name parameter is filled, we reach this line:

            AuthenticationStatus status = securityContext.authenticate(
request, response, withParams().credential(new
CallerOnlyCredential(name)));

This will ask the Java EE server to process an authentication. But...based on what? That's where our HttpAuthenticationMechanism implementation comes in.

As the preceding code created CallerOnlyCredential, our authentication mechanism will be based on it:

            Credential credential = httpMessageContext.getAuthParameters()
.getCredential();
if (!(credential instanceof CallerOnlyCredential)) {
throw new IllegalStateException("Invalid mechanism");
}

CallerOnlyCredential callerOnlyCredential =
(CallerOnlyCredential) credential;

And once we have a credential instance, we can check if the user "exists":

            if ("user".equals(callerOnlyCredential.getCaller())) {
...
} else{
throw new AuthenticationException();
}

As an example, we have just compared the names, but in a real case you could search your database, an LDAP server, and so on.

If the user exists, we proceed with the authentication based on some rules:

return httpMessageContext.notifyContainerAboutLogin
(callerOnlyCredential.getCaller(), new HashSet<>(asList("role1","role2")));

In this case, we have said that the user has access to "role1" and "role2".

Once the authentication is done, it comes back to the servlet and uses the result to finish the process:

        response.getWriter().write("Role "role1" access: " + 
request.isUserInRole("role1") + " ");
response.getWriter().write("Role "role2" access: " +
request.isUserInRole("role2") + " ");
response.getWriter().write("Role "role3" access: " +
request.isUserInRole("role3") + " ");
response.getWriter().write("Access to /authServlet? " +
securityContext.hasAccessToWebResource("/authServlet") + " ");

So, this code will print true for "role1" and "role2", and false for "role3". Because "/authServlet" is allowed for "role1", the user will have access to it.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.163.62