users@javaee-security-spec.java.net

[javaee-security-spec users] Re: JWT authentication mechanism

From: Abhishek Gupta <abhirockzz_at_gmail.com>
Date: Tue, 22 Mar 2016 20:25:43 +0530

Arjan, thanks for your inputs!

The ContainerResponseFilter does two things

1. check whether the token validation (by the request filter) was
successful to begin with - it uses JAX-RS specific API i.e. the
ContainerRequestFilter implementation adds a *custom* property (indicating
success or failure of JWT token validation) to a Map exposed by the
ContainerRequestContext object and this is read by the response filter

2. if yes, it adds the JWT to the response header

If I (use the above snippet and) add the header using HttpServletResponse
(based on the JWT validation criteria), then

1. the request would be intercepted by the 'authentication mechanism'
2. token would be validated and resource access would be allowed
3. the HTTP response would contain my custom header...

Correct ?

Regards
Abhishek



On Mon, Mar 21, 2016 at 10:13 PM, arjan tijms <arjan.tijms_at_gmail.com> wrote:

> Hi,
>
> In reply to http://2.long4.me/t/503076446527416108
>
> I just need to validate the Json Web Token and do not require to invoke an
>> Identity Store impl within the JASPIC component. Is this valid ?
>>
>
>> public class JWTAuthMechanism implements HttpAuthenticationMechanism {
>> @Override
>> public AuthStatus validateRequest(HttpServletRequest request,
>> HttpServletResponse response, HttpMessageContext httpMessageContext) throws
>> AuthException {
>>
>> System.out.println("JSR 375 Auth Mechanism in action...");
>> String authHeaderVal = request.getHeader("Authorization");
>>
>> //consume JWT i.e. execute signature validation
>> if (authHeaderVal.startsWith("Bearer")) {
>> try {
>> System.out.println("JWT based Auth in action... time
>> to verify it");
>> final String subject = validate(authHeaderVal.split("
>> ")[1]); //use jose4j to validate JWT
>>
>> return httpMessageContext.notifyContainerAboutLogin(
>> subject,
>> Collections.EMPTY_LIST);
>>
>> } catch (InvalidJwtException ex) {
>>
>> Logger.getLogger(JWTAuthMechanism.class.getName()).log(Level.SEVERE, null,
>> ex);
>> throw new AuthException("JWT token validation
>> failed");
>> }
>> }
>>
>> return httpMessageContext.doNothing();
>> //..........
>> }
>
>
> This is valid. The HttpAuthenticationMechanism is under no obligation to
> delegate to the identity store.
>
> In this case you *could* (but don't have to) delegate the logic from the
> validate() method to an identity store. It's kinda like in a JSF backing
> you can delegate certain things to an (injected) service, but technically
> you can perform the business logic directly in the backing bean as well.
>
>
> 1. How do I scope this to certain URLs (or resources) only ? e.g. the
>> JWTAuthFilter was scoped to specific JAX-RS resources by extending
>> javax.ws.rs.core.Application
>
>
> This is a good point. JSR 375 has not yet arrived at the point where we
> implemented this. Spec lead Alex did propose this though and it's in the
> JSR (see https://www.jcp.org/en/jsr/detail?id=375):
>
> *"We propose a means to enable each servlet to be configured with
> different authentication methods within a single web application.
> Currently, Java EE web applications only support one selected
> authentication method per application. This proposal would enable different
> servlet-based modules (e.g. JSF and REST) to be configured with different
> authentication methods within the same application deployment."*
>
> For now you'll have to manually check the URL in the authentication
> mechanism, but it's a good reminder to the EG I think that we need to look
> at this soon.
>
>
> 2. Is there a way to inject the authentication response (by JASPIC) in the
>> JAX-RS container response filter ? Currently it makes use of a custom Map
>> exposed by the ContainerRequestFilter instance to check whether the token
>> validation was successful to begin with
>
>
> What "authentication response" were you exactly looking for? Is it the
> "failed/succeeded" status, or something else?
>
> If you just need to set a header, like in
> https://gist.githubusercontent.com/abhirockzz/7120429acb04186da340/raw/881954ed4372ae6c603883e0f9be389f3bf2d8fa/JWTResponseFilter.java
> you can do it directly from the authentication mechanism.
>
> The authentication mechanism can use the HttpServletResponse and set a
> header itself. Or is there a specific reason it needs to be done in
> the ContainerResponseFilter?
>
> Kind regards,
> Arjan Tijms
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>