问题:我使用的是MFP 7.1版本。
我在我的android应用中使用MFP 7.1和oauth.tai_1.0.0.jar来进行应用认证,并在MFP端定义了领域。每次我试图注册到应用程序时,我都会在日志中看到以下信息
OAuthTAI认证失败,Status=401,WWW-Authenticate.Bearer realm="imfAuthentication",scope="UserAuthRealm"。Bearer realm="imfAuthentication", scope="UserAuthRealm"
这并没有阻止应用程序的流动。我只是在日志中得到这个错误,而且这个错误是在realm类的init方法被初始化之前看到的,之后一切正常。
我想知道为什么我会得到这个错误。
分析一下。
我已经检查了android中的挑战处理程序,它是正常的。我还重新安装了一个应用程序,以确保从MFP发送新的访问令牌.我还检查了MFP的Oauth jar,并检查了401错误情况,它检查invalid_token和invalid_authorization。但在我的情况下,这两个都不存在,因为我在错误描述中没有得到这个。我定义了自定义身份验证器类,它被映射到UserAuthReal,代码如下。
CustomUserAuthenticator.java:
package com.ibm.mfp;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.worklight.core.auth.impl.AuthenticationContext;
import com.worklight.server.auth.api.AuthenticationResult;
import com.worklight.server.auth.api.AuthenticationStatus;
import com.worklight.server.auth.api.MissingConfigurationOptionException;
import com.worklight.server.auth.api.UserIdentity;
import com.worklight.server.auth.api.WorkLightAuthenticator;
public class CustomUserAuthenticator implements WorkLightAuthenticator {
private static final long serialVersionUID = -548850541866024092L;
private static final Logger logger = Logger.getLogger(CustomUserAuthenticator.class.getName());
private String pin;
private String userName;
private String uniqueID;
private String userNumber;
private String userAuthFlag;
private String registrationNumber;
protected Map<String, Object> authenticationData;
public void init(Map<String, String> options) throws MissingConfigurationOptionException {
logger.info("CustomUserAuthenticator initialized");
}
public AuthenticationResult processRequest(HttpServletRequest request, HttpServletResponse response,
boolean isAccessToProtectedResource) throws IOException, ServletException {
String clientID = AuthenticationContext.getCurrentClientId();
logger.info("CustomUserAuthenticator :: processRequest : clientID : " + clientID);
String requestURI = request.getRequestURI();
logger.info("CustomUserAuthenticator :: processRequest : request.getRequestURI() :" + requestURI);
String requestQueryString = request.getQueryString();
requestQueryString = null;
logger.info("CustomUserAuthenticator :: processRequest : request.getQueryString() :" + requestQueryString);
// Request the epin from the user
if (request.getRequestURI().contains("/ADIBMBA/auth/v2/auth")) {
this.pin = request.getParameter("pin");
this.userName= request.getParameter("userName");
this.uniqueID = request.getParameter("uniqueID");
this.userNumber = request.getParameter("userNumber");
this.userAuthFlag = request.getParameter("userAuthFlag");
this.registrationNumber = request.getParameter("registrationNumber");
if (null != this.customerNumber) {
logger.info(
"CustomUserAuthenticator :: processRequest : request.getRequestURI() : getParameter customerNumber : "
+ this.customerNumber);
}
if (null != pin && pin.length() > 0) {
return AuthenticationResult.createFrom(AuthenticationStatus.SUCCESS);
} else {
response.setContentType("application/json; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().print("{\"authStatus\":\"required\", \"errorMessage\":\"Please enter epin\"}");
return AuthenticationResult.createFrom(AuthenticationStatus.CLIENT_INTERACTION_REQUIRED);
}
}
if (!isAccessToProtectedResource) {
return AuthenticationResult.createFrom(AuthenticationStatus.REQUEST_NOT_RECOGNIZED);
}
response.setContentType("application/json; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().print("{\"authStatus\":\"required\"}");
return AuthenticationResult.createFrom(AuthenticationStatus.CLIENT_INTERACTION_REQUIRED);
}
public boolean changeResponseOnSuccess(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String requestURI2 = request.getRequestURI();
logger.info("CustomUserAuthenticator :: changeResponseOnSuccess : request ");
logger.info("CustomUserAuthenticator :: changeResponseOnSuccess : response ");
// first worked partially with if
// (request.getRequestURI().contains("/ADIBMBA/auth/v2/auth")){
if (request.getRequestURI().contains("/ADIBMBA/mainapps/services/apis/App/iOSnative")
|| (request.getRequestURI().contains("/ADIBMBA/auth/v2/auth"))) {
response.setContentType("application/json; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().print("{\"authStatus\":\"complete\"}");
return true;
}
return false;
}
public AuthenticationResult processAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
String errorMessage) throws IOException, ServletException {
logger.info("CustomUserAuthenticator :: processAuthenticationFailure");
response.setContentType("application/json; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.getWriter().print("{\"authStatus\":\"failed\", \"errorMessage\":" + errorMessage + ","
+ (String) authenticationData.get("error") + "}");
return AuthenticationResult.createFrom(AuthenticationStatus.CLIENT_INTERACTION_REQUIRED);
}
public AuthenticationResult processRequestAlreadyAuthenticated(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
logger.info("CustomUserAuthenticator :: processRequestAlreadyAuthenticated");
return
AuthenticationResult.createFrom(AuthenticationStatus.
REQUEST_NOT_RECOGNIZED);
}
public Map<String, Object> getAuthenticationData() {
authenticationData = new HashMap<String, Object>();
authenticationData.put("userName", userName);
authenticationData.put("uniqueID", uniqueID);
authenticationData.put("pin", pin);
authenticationData.put("userNumber", userNumber);
authenticationData.put("userAuthFlag", userAuthFlag);
authenticationData.put("registrationNumber", registrationNumber);
return authenticationData;
}
public HttpServletRequest getRequestToProceed(HttpServletRequest request, HttpServletResponse response,
UserIdentity userIdentity) throws IOException {
return null;
}
@Override
public WorkLightAuthenticator clone() throws CloneNotSupportedException {
CustomUserAuthenticator otherAuthenticator = (CustomUserAuthenticator) super.clone();
return otherAuthenticator;
}
}
总结:如果应用流程正常,那么为什么我在日志中出现OAuthTAI 401错误。
如果应用流程正常,那么为什么我在日志中得到这个OAuthTAI 401错误。假设如果是token & id token的问题,那么我应该不能访问受保护的资源数据。应用程序不应该允许我继续下去。
从描述和评论来看,你似乎把Liberty的OAuth TAI和MFP的OAuth安全模型搞混了。
MFP的OAuth安全模型用于保护MFP资源(适配器和运行时端点),而Liberty的OAuth TAI用于保护部署在Liberty服务器上的资源(例如:Web应用程序)。
你所遵循的链接详细介绍了MFP服务器可以作为部署在Liberty服务器上的资源的OAuth服务器的步骤。
从描述和扩展的自定义认证器中可以看出,MFP服务器可以作为Liberty服务器中部署的资源的OAuth服务器。WorklightAuthenticator
你是依靠MFP的安全框架来完成安全验证的。如果要求您的MFP适配器受到OAuth安全保护,并且设备开始从MFP服务器获取OAuth令牌,那么您应该使用MFP的OAuth安全,而不是求助于Liberty OAuth TAI。MFP的OAuth安全框架开箱即用,无需配置TAI。
请参考下面的链接,以便更好的理解和工作示例。
b) Java适配器
c) 自定义认证器