我正在构建移动应用和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方法。
答案 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
}