泽西网络服务基本身份验证不要求用户名和密码

问题描述 投票:0回答:2

我已经实现了球衣网络服务,并尝试在有人从浏览器调用网络服务时询问用户名和密码来验证网络服务。我不确定下面的代码中缺少什么,当有人调用 Web 服务 URL 时,它不会要求提供凭据,而是直接访问下面的 AuthFilter 类。请帮忙查找问题。这是下面的代码。 我还添加了我之前使用的 CXF 身份验证,我现在尝试使用 jersey 来实现。

AuthFilter 类

package com.myProj.inventory.ws.rest.v1.security;

import java.util.Set;

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import com.myProj.commons.user.model.DetailedUser;
import com.myProj.commons.user.service.UserInfoService;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;

@Component
public class AuthFilter implements ContainerRequestFilter {

    private static Logger logger = Logger.getLogger(AuthenticationFilter.class);

    private static final String RIGHT_INVOKE_WEBSERVICE = "INVOKE_WEBSERVICE";

    @Autowired
    private UserInfoService userInfoService;

    @Override
    public ContainerRequest filter(ContainerRequest containerRequest)
            throws WebApplicationException {

        // Get the authentification passed in HTTP headers parameters
        String auth = containerRequest.getHeaderValue("authorization");

        // If the user does not have the right (does not provide any HTTP Basic
        // Auth)
        if (auth == null) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }

        // lap : loginAndPassword
        String[] lap = BasicAuth.decode(auth);

        // If login or password fail
        if (lap == null || lap.length != 2) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }

        try {
            boolean isRightExists = false;
            // DO YOUR DATABASE CHECK HERE (replace that line behind)...
            DetailedUser detailedUser = userInfoService.readUserInfoAsUser(
                    lap[0], lap[1]);

            if (detailedUser != null) {
                Set<String> rights = detailedUser.getRights();

                for (String right : rights) {
                    // TODO: We have additional rights to check
                    if (RIGHT_INVOKE_WEBSERVICE.equalsIgnoreCase(right)) {
                        isRightExists = true;
                    }
                }
            }

            if (!isRightExists) {
                throw new WebApplicationException(Status.UNAUTHORIZED);
            }

        } catch (AuthenticationException ae) {
            throw new WebApplicationException(Status.UNAUTHORIZED);
        }

        return containerRequest;
    }
}

凭证解码类

package com.myProj.inventory.ws.rest.v1.security;

import javax.xml.bind.DatatypeConverter;

public class BasicAuth {
    /**
     * Decode the basic auth and convert it to array login/password
     * @param auth The string encoded authentification
     * @return The login (case 0), the password (case 1)
     */
    public static String[] decode(String auth) {
        //Replacing "Basic THE_BASE_64" to "THE_BASE_64" directly
        auth = auth.replaceFirst("[B|b]asic ", "");

        //Decode the Base64 into byte[]
        byte[] decodedBytes = DatatypeConverter.parseBase64Binary(auth);

        //If the decode fails in any case
        if(decodedBytes == null || decodedBytes.length == 0){
            return null;
        }

        //Now we can convert the byte[] into a splitted array :
        //  - the first one is login,
        //  - the second one password
        return new String(decodedBytes).split(":", 2);
    }
}

Web.xml 球衣 servlet 映射

<servlet>
    <servlet-name>restwebservice</servlet-name>
    <servlet-class>
        com.sun.jersey.spi.spring.container.servlet.SpringServlet
    </servlet-class>
    <init-param>

    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>com.sun.jersey.api.container.filter.LoggingFilter;com.guthyrenker.inventory.ws.rest.v1.security.AuthFilter</param-value>
    </init-param>
    <init-param>
        <param-name>
            com.sun.jersey.config.property.packages
         </param-name>

        <param-value>com.guthyrenker.inventory.ws.rest.v1.service</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>restwebservice</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

CXF基本认证

公共类 AuthenticationFilter 实现 RequestHandler { 私有静态 Logger 记录器 = Logger.getLogger(AuthenticationFilter.class);

private static final String RIGHT_INVOKE_WEBSERVICE = "INVOKE_WEBSERVICE";

@Autowired
private UserInfoService userInfoService;

public Response handleRequest(Message request, ClassResourceInfo resourceClass) {

    AuthorizationPolicy policy = (AuthorizationPolicy) request.get(AuthorizationPolicy.class);
    if (policy == null) {
        // issue an authentication challenge to give invoker a chance to reply with credentials
        // (this is useful if web service is being called from a browser)
        return Response.status(Status.UNAUTHORIZED).header("WWW-Authenticate", "Basic").build();
    }

    // check authorization realm - we currently only support Basic authentication
    String realm = policy.getAuthorizationType();
    if (!"Basic".equalsIgnoreCase(realm)) {
        return Response.status(Status.UNAUTHORIZED).header("WWW-Authenticate", "Basic").build();
    }

    final String username = policy.getUserName();
    final String password = policy.getPassword();

    try {
        boolean isRightExists = false;

        DetailedUser detailedUser = userInfoService.readUserInfoAsUser(username, password);

        if (detailedUser != null) {
            Set<String> rights = detailedUser.getRights();

            for (String right : rights) {
                //TODO: We have additional rights to check
                if (RIGHT_INVOKE_WEBSERVICE.equalsIgnoreCase(right)) {
                    isRightExists = true;
                }
            }
        }

        if (!isRightExists) {
            return ErrorFactory.newFault(CommonError.ACCESS_DENIED);
        }

    } catch (AuthenticationException ae) {
        return ErrorFactory.newFault(CommonError.AUTHENTICATION_FAILED);
    }

    return null;
}
java web-services rest jersey jersey-client
2个回答
0
投票

您似乎对基本身份验证和表单身份验证感到困惑。基本身份验证使用标头进行工作,而表单身份验证则显示登录表单。基本身份验证基于以下提到的标头进行工作:

WWW-Authenticate

0
投票

对于仍在寻找解决方案的人,这是我解决问题的方法:

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
    String authorization = ((ContainerRequest) requestContext.getRequest()).getHeaderString(HttpHeaders.AUTHORIZATION);

    if (authorization == null) {
        final ResponseBuilder builder = Response.status(Response.Status.UNAUTHORIZED)
                .header(HttpHeaders.WWW_AUTHENTICATE, "Basic");
        requestContext.abortWith(builder.build());
        return;
    }

    // continue with authentication
}
© www.soinside.com 2019 - 2024. All rights reserved.