0

i am trying to do some authorization and authentication with JAX-RS, i have the html files and the java files in different host and i am having some CROSS problems. i read this question about CROSS, i have a preflight cross so i do the same in the question:


@Provider
@Logged
public class SecurityFilter implements ContainerRequestFilter, ContainerResponseFilter {

    private static final String AUTHORIZATION_HEADER_KEY = "Authorization";
    private static final String AUTHORIZATION_HEADER_PREFIX = "Basic ";

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

        if(isPreflightRequest(requestContext)){
            try {

                List<String> authHeader = requestContext.getHeaders().get(AUTHORIZATION_HEADER_KEY);

                if (authHeader.size() > 0) {

                    // Extracting credentials from header
                    String authToken = authHeader.get(0);
                    authToken = authToken.replaceFirst(AUTHORIZATION_HEADER_PREFIX, "");
                    String decodedString = new String(Base64.getDecoder().decode(authToken));
                    StringTokenizer tokenizer = new StringTokenizer(decodedString, ":");
                    String username = tokenizer.nextToken();
                    String password = tokenizer.nextToken();

                    // Validating credentials
                    UserAppService userAppService= new UserAppService();
                    String role = userAppService.validateUser(username, password);
                    if(!(role.equals("error") || role.equals("not found") || role.equals("no match"))) {
                        requestContext.getHeaders().add("role", role);
                        userAppService.close();
                        return;
                    } else {
                        userAppService.close();
                        requestContext.abortWith(Response
                                .status(Response.Status.UNAUTHORIZED)
                                .header("Access-Control-Allow-Origin", "*")
                                .entity("Invalid credentials")
                                .build());
                    }
                } else {
                }

            } catch (NullPointerException e) {
                requestContext.abortWith(Response
                        .status(Response.Status.UNAUTHORIZED)
                        .header("Access-Control-Allow-Origin", "*")
                        .entity("Credentials not provided")
                        .build());
            }
        }
    }

    private static boolean isPreflightRequest(ContainerRequestContext request) {
        return request.getHeaderString("Origin") != null
                && request.getMethod().equalsIgnoreCase("OPTIONS");
    }

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        if (requestContext.getHeaderString("Origin") == null) {
            return;
        }
        if (isPreflightRequest(requestContext)) {
            responseContext.getHeaders().add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
            responseContext.getHeaders().add("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type");
            responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        }
        responseContext.getHeaders().add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        responseContext.getHeaders().add("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type");
        responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
    }
}

but i have the error No 'Access-Control-Allow-Origin' header is present on the requested resource.

The @Logged annotation is make by me and is used for authentication (that actually works, i tested it in postman). also i need to add the header Authorization in the request. i do like this:

    let username= form.elements[0].value;
    let password= form.elements[1].value;
    xh.withCredentials= true;
    xh.setRequestHeader("Authorization", "Basic "+ btoa('username:password'));
    xh.send(new FormData(form));

but i dont know if is correct (i mean if the SecurityFilter can get this tokens in some way for that the code above works, the first filter method. Sending like postman do it with the basic authorization)

here is the rest method that responsa to the CROSS call:

@POST
    @Logged
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public Response create(MultipartFormDataInput input){
        try {
            Map<String, List<InputPart>> uploadForm= input.getFormDataMap();
            String type= uploadForm.get("case").get(0).getBodyAsString();
            String username= uploadForm.get("form-username").get(0).getBodyAsString();
            String password= uploadForm.get("form-password").get(0).getBodyAsString();
            String role= userAppService.validateUser(username, password);
            return Response.status(Response.Status.FOUND).entity(role).build();
        } catch (IOException e) {
            userAppService.close();
            return Response.status(Response.Status.BAD_REQUEST).header("Access-Control-Allow-Origin", "*").entity(e).build();
        } catch(Exception e){
            userAppService.close();
            return Response.status(Response.Status.FORBIDDEN).header("Access-Control-Allow-Origin", "*").entity(e).build();

        }
Ernesto
  • 67
  • 7

0 Answers0