Jersey Web服务基本身份验证不要求用户名和密码

时间:2014-10-14 11:52:24

标签: java web-services rest jersey jersey-client

我已经实现了jersey webservice并尝试通过在某人从浏览器调用webservice时询问用户名和密码来验证webservice。我不确定我在下面的代码中缺少什么,当有人调用webservice 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 jersey servlet mapping

<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基本身份验证

public class AuthenticationFilter实现RequestHandler {     private static Logger 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;
}

1 个答案:

答案 0 :(得分:0)

您似乎在基本身份验证和表单身份验证之间感到困惑。基本身份验证使用标头,而表单身份验证提供登录表单。基本身份验证基于下面提到的标题工作:

WWW-Authenticate