我已经实现了jersey webservice并尝试通过在某人从浏览器调用webservice时询问用户名和密码来验证webservice。我不确定我在下面的代码中缺少什么,当有人调用webservice URL时,它不是要求凭据,而是直接转到下面的AuthFilter类。请帮助找到问题。这是下面的代码。 我还添加了我之前使用过的CXF身份验证,我正在尝试使用jersey实现。
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);
}
}
<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>
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;
}
答案 0 :(得分:0)
您似乎在基本身份验证和表单身份验证之间感到困惑。基本身份验证使用标头,而表单身份验证提供登录表单。基本身份验证基于下面提到的标题工作:
WWW-Authenticate