首页 > 解决方案 > 使用 javaScript 和 JAX-RS 的凭据

问题描述

我正在尝试使用 JAX-RS 进行一些授权和身份验证,我在不同的主机中有 html 文件和 java 文件,我遇到了一些 CROSS 问题。我读了这个 关于 CROSS 的问题,我有一个飞行前交叉,所以我在这个问题中做同样的事情:


@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", "*");
    }
}

但我有错误No 'Access-Control-Allow-Origin' header is present on the requested resource.

@Logged 注释由我制作并用于身份验证(实际上有效,我在邮递员中对其进行了测试)。我还需要在请求中添加标头授权。我喜欢这样:

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

但我不知道是否正确(我的意思是如果 SecurityFilter 可以通过某种方式获取此令牌以使上面的代码有效,则为第一种过滤方法。像邮递员一样发送基本授权)

这是响应 CROSS 调用的其余方法:

@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();

        }

标签: javascripthtmlxmlhttprequestjax-rscross-domain

解决方案


推荐阅读