简体   繁体   中英

Java JAX-RS Name Binding Not working

I am working on an authentication filter for my REST service.

Can some one please explain why this name binding not works.

When I make a post request, I can receive the String "Tokenized", but log does not print "Inside the filter".

import java.io.IOException;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.FormParam;
import javax.ws.rs.NameBinding;
import javax.ws.rs.Produces;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Target;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;



@Path("/authentication")
public class AuthenticationHandler {

    final static Logger log = Logger.getLogger(AuthenticationHandler.class);

    @NameBinding
    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface Secured {
    }

    @Secured
    @Provider
    @Priority(Priorities.AUTHENTICATION)
    public class AuthenticationFilter implements ContainerRequestFilter {

        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {

            log.info("Inside the filter");

            // Get the HTTP Authorization header from the request
            String authorizationHeader
                    = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

            // Check if the HTTP Authorization header is present and formatted correctly 
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
                throw new NotAuthorizedException("Authorization header must be provided");
            }

            // Extract the token from the HTTP Authorization header
            String token = authorizationHeader.substring("Bearer".length()).trim();

            try {

                // Validate the token
                validateToken(token);

            } catch (Exception e) {
                requestContext.abortWith(
                        Response.status(Response.Status.UNAUTHORIZED).build());
            }
        }

        private void validateToken(String token) throws Exception {
            // Check if it was issued by the server and if it's not expired
            // Throw an Exception if the token is invalid
        }


    }

    @POST
    @Secured
    @Path("/request_token")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response authenticateUser(@FormParam("username") String username,
            @FormParam("password") String password) {

        try {

            // Authenticate the user using the credentials provided
            authenticate(username, password);

            // Issue a token for the user
            String token = issueToken(username);

            // Return the token on the response
            return Response.ok(token).build();

        } catch (Exception e) {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
    }



    private boolean authenticate(String username, String password) throws Exception {
        return true;
    }

    private String issueToken(String username) {
        return "Tokenized";
    }

}

Thanks for the tip peeskillet.

It is now working fine after creating separate classes for Name Bind and Filter. I'm posting the solution below if anyone required.

My problem now is, is there a way to keep this two classes in a separate package, because I tried by putting it on my Util package and it didn't work properly.

peeskillet : Thanks for the tip again.

AuthenticationFilter.java

import com.binosaurs.sf.backend.handler.Secured;
import com.binosaurs.sf.backend.util.*;
import java.io.IOException;
import javax.annotation.Priority;
import javax.ws.rs.NotAuthorizedException;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.apache.log4j.Logger;



    @Secured
    @Provider
    @Priority(Priorities.AUTHENTICATION)
    public class AuthenticationFilter implements ContainerRequestFilter {

        // Get Log4j Logger
    final static Logger log = Logger.getLogger(AuthenticationFilter.class);

        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {

            log.info("Inside the filter");

            // Get the HTTP Authorization header from the request
            String authorizationHeader
                    = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

            // Check if the HTTP Authorization header is present and formatted correctly
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
                throw new NotAuthorizedException("Authorization header must be provided");
            }

            // Extract the token from the HTTP Authorization header
            String token = authorizationHeader.substring("Bearer".length()).trim();

            try {

                // Validate the token
                validateToken(token);

            } catch (Exception e) {
                requestContext.abortWith(
                        Response.status(Response.Status.UNAUTHORIZED).build());
            }
        }

        private void validateToken(String token) throws Exception {
            // Check if it was issued by the server and if it's not expired
            // Throw an Exception if the token is invalid
        }


    }

Secured.java

    /*
    * To change this license header, choose License Headers in Project Properties.
    * To change this template file, choose Tools | Templates
    * and open the template in the editor.
    */
    package com.binosaurs.sf.backend.handler;

    import com.binosaurs.sf.backend.util.*;
    import static java.lang.annotation.ElementType.METHOD;
    import static java.lang.annotation.ElementType.TYPE;
    import java.lang.annotation.Retention;
    import static java.lang.annotation.RetentionPolicy.RUNTIME;
    import java.lang.annotation.Target;
    import javax.ws.rs.NameBinding;

    @NameBinding
    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface Secured {
    }

AuthenticationHandler.java

    package com.binosaurs.sf.backend.handler;
    import javax.ws.rs.core.Response;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.POST;
    import javax.ws.rs.Path;
    import javax.ws.rs.FormParam;
    import javax.ws.rs.Produces;
    import org.apache.log4j.Logger;



    @Path("/authentication")
    public class AuthenticationHandler {

        final static Logger log = Logger.getLogger(AuthenticationHandler.class);

        @POST
        @Secured
        @Path("/request_token")
        @Produces(MediaType.APPLICATION_JSON)
        @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
        public Response authenticateUser(@FormParam("username") String username,
                @FormParam("password") String password) {

            try {

                // Authenticate the user using the credentials provided
                authenticate(username, password);

                // Issue a token for the user
                String token = issueToken(username);

                // Return the token on the response
                return Response.ok(token).build();

            } catch (Exception e) {
                return Response.status(Response.Status.UNAUTHORIZED).build();
            }
        }



        private boolean authenticate(String username, String password) throws Exception {
            return true;
        }

        private String issueToken(String username) {
            return "Tokenized";
        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM