How it works...

Let's split up the code we've provided so that we can 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>

We're also 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"})

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

Another important factor in this scene is the following one:

    @Inject
private SecurityContext securityContext;

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

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

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

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

Since 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;

Once we have a credential instance, we can check whether the user exists:

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

In this example, we have just compared the names of the user, but in a real-life scenario, you could search your database, a Lightweight Directory Access Protocol (LDAP) server, and so on.

If the user exists, we proceed with the authentication process 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 authentication is complete, it goes 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
18.216.186.164