Restful api如何在基本的http auth之后传递信息

时间:2016-03-14 21:21:21

标签: java rest authentication servlets java-ee

我正在构建移动应用和Restful API,我希望应用的用户能够在没有身份验证的情况下获取他想要的资源。但如果他想要发帖,他必须输入他的用户名并通过。 我已经通过在web.xml中添加过滤器来进行HTTP基本身份验证。

<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>org.service.RestAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/webapi/*</url-pattern>
</filter-mapping>

并且有类

public class AuthenticationService {
ClientsService s = new ClientsService();
public boolean authenticate(String authCredentials) {

    if (null == authCredentials)
        return false;
    // header value format will be "Basic encodedstring" for Basic
    // authentication. Example "Basic YWRtaW46YWRtaW4="
    final String encodedUserPassword = authCredentials.replaceFirst("Basic"
            + " ", "");
    String usernameAndPassword = null;
    try {
        byte[] decodedBytes = Base64.decode(
                encodedUserPassword);
        usernameAndPassword = new String(decodedBytes, "UTF-8");
    } catch (IOException e) {
        e.printStackTrace();
    }
    final StringTokenizer tokenizer = new StringTokenizer(
            usernameAndPassword, ":");
    final String username = tokenizer.nextToken();
    final String password = tokenizer.nextToken();
    boolean authenticationStatus =s.auth(username, password);

    return authenticationStatus;
}
}

和过滤器

public class RestAuthenticationFilter implements javax.servlet.Filter {
public static final String AUTHENTICATION_HEADER = "Authorization";

@Override
public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filter) throws IOException, ServletException {
    if (request instanceof HttpServletRequest) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String authCredentials = httpServletRequest
                .getHeader(AUTHENTICATION_HEADER);

        // better injected
        AuthenticationService authenticationService = new AuthenticationService();

        boolean authenticationStatus = authenticationService
                .authenticate(authCredentials);

        if (authenticationStatus) {
            filter.doFilter(request, response);

        } else {
            if (response instanceof HttpServletResponse) {
                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                httpServletResponse
                        .setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            }
        }
    }
}

@Override
public void destroy() {
}

@Override
public void init(FilterConfig arg0) throws ServletException {
}
}

我需要知道的是:如何在验证后将用户名和密码或者客户端的ID传递给Restful方法。

1 个答案:

答案 0 :(得分:0)

与我的评论不同的解决方案:您可以查找HTTP请求方法,然后在调用身份验证方法时做出决定:

public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain filter) throws IOException, ServletException {
    if (request instanceof HttpServletRequest) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String authCredentials = httpServletRequest
                .getHeader(AUTHENTICATION_HEADER);

        boolean authenticationStatus;

        // check request method
        if (((HttpServletRequest).request).getMethod().equals("GET")) {
            authenticationStatus=true;
        } else {
            // better injected
            AuthenticationService authenticationService =
                  new AuthenticationService();
            authenticationStatus = authenticationService
                .authenticate(authCredentials);
        }

        if (authenticationStatus) {
            filter.doFilter(request, response);

        } else {
            if (response instanceof HttpServletResponse) {
                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
                httpServletResponse
                        .setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            }
        }
    }
}

<强>更新

使用JAX-RS,获取更多请求信息的可能解决方案可能如下所示:

import javax.ws.rs.*;
import javax.ws.rs.core.Context;

@GET
@Path("offers")
@Produces("application/xml")
public YourList getOffers(@Context HttpServletRequest request)
{
    System.out.println("request to "+request.getRequestURI()+" , Auth: "+request.getHeader(AUTHENTICATION_HEADER));

// more stuff for obtaining data
}