自訂中介
OAuth 2.0 中介是在 OAuth 2.0 訊息處理期間,用來作為一項執行自訂後置處理的回呼。
撰寫 OAuth 2.0 中介程式
如果要撰寫中介程式,您必須實作名稱為 com.ibm.oauth.core.api.oauth20.mediator.OAuth20Mediator 的介面。您可以實作下列一或多個方法,來執行自訂後置處理程序。
void init(OAuthComponentConfiguration config)
當建立這個物件的實例時,Factory 會呼叫這個方法。
void mediateAuthorize(AttributeList attributeList)
在進行基本的訊息驗證和處理之後,核心元件會呼叫這個方法,以容許元件消費者在 processAuthorization 方法中進行任何後置自訂處理。
void mediateAuthorizeException(AttributeList attributeList, OAuthException exception)
當發生通訊協定異常狀況時,核心元件會呼叫這個方法,以容許元件消費者在 processAuthorization 方法中進行任何後置自訂處理。
void mediateResource(AttributeList attributeList)
在進行基本的訊息驗證和處理之後,核心元件會呼叫這個方法,以容許元件消費者在 processResourceRequest 方法中進行任何後置自訂處理。
void mediateResourceException(AttributeList attributeList, OAuthException exception)
當發生通訊協定異常狀況時,核心元件會呼叫這個方法,以容許元件消費者在 processResourceRequest 方法中進行任何後置自訂處理。
void mediateToken(AttributeList attributeList)
在進行基本的訊息驗證和處理之後,核心元件會呼叫這個方法,以容許元件消費者在 processTokenRequest 方法中進行任何後置自訂處理。
void mediateTokenException(AttributeList attributeList, OAuthException exception)
當發生通訊協定異常狀況時,核心元件會呼叫這個方法,以容許元件消費者在 processTokenRequest 方法中進行任何後置自訂處理。對 OAuth 提供者啟用 OAuth20 2.0 中介程式
如果要新增自訂中介程式到特定 OAuth 2.0 服務提供者中,請更新 server.xml 檔中的提供者定義。 請新增 oauthProvider 元素的 mediatorClassname 屬性,然後指定中介的類別名稱。 您也可以利用 oauthProvider 元素的 mediatorClassname 子元素來指定中介的多個類別名稱。 如果指定了多個中介,這些中介會依照它們的指定順序來啟動。 另外,您也必須定義包含中介類別的 library 元素,然後利用 libraryRef 屬性來參照程式庫。
下列範例顯示 server.xml 檔之提供者定義中的自訂中介項目範例:
<oauthProvider id="OAuthConfigSample" libraryRef="myLib"
mediatorClassname="com.ibm.ws.security.oauth20.mediator.ResourceOwnerValidationMediator" ...>
...
</oauthProvider>
<library id="myLib">
<fileset dir="C:\mydir" includes="myLib.jar" />
</library>
下列程式碼範例在資源擁有者密碼認證流程中,利用 WebSphere® Application Server 使用者登錄來實作認證驗證。
package com.ibm.ws.security.oauth20.mediator;
import com.ibm.oauth.core.api.attributes.AttributeList;
import com.ibm.oauth.core.api.config.OAuthComponentConfiguration;
import com.ibm.oauth.core.api.error.OAuthException;
import com.ibm.oauth.core.api.error.oauth20.OAuth20MediatorException;
import com.ibm.oauth.core.api.oauth20.mediator.OAuth20Mediator;
import com.ibm.oauth.core.internal.oauth20.OAuth20Constants;
import com.ibm.websphere.security.CustomRegistryException;
import com.ibm.websphere.security.PasswordCheckFailedException;
import com.ibm.websphere.security.UserRegistry;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class ResourceOwnerValidationMedidator implements OAuth20Mediator {
private static final String CLASS = ResourceOwnerValidationMedidator.class.getName();
private static final Logger LOG = Logger.getLogger(CLASS);
private UserRegistry reg = null;
public void init(OAuthComponentConfiguration config) {
try {
InitialContext ctx = new InitialContext();
reg = (UserRegistry) ctx.lookup("UserRegistry");
} catch(NamingException ne) {
LOG.log(Level.SEVERE, "Cannot lookup UserRegistry", ne);
}
}
public void mediateAuthorize(AttributeList attributeList)
throws OAuth20MediatorException {
// nothing to do here
}
public void mediateAuthorizeException(AttributeList attributeList,
OAuthException exception)
throws OAuth20MediatorException {
// nothing to do here
}
public void mediateResource(AttributeList attributeList)
throws OAuth20MediatorException {
// nothing to do here
}
public void mediateResourceException(AttributeList attributeList,
OAuthException exception)
throws OAuth20MediatorException {
// nothing to do here
}
public void mediateToken(AttributeList attributeList)
throws OAuth20MediatorException {
final String methodName = "mediateToken";
LOG.entering(CLASS, methodName, attributeList);
if("password".equals(attributeList.getAttributeValueByName("grant_type"))) {
String username = attributeList.getAttributeValueByName("username");
String password = attributeList.getAttributeValueByName("password");
try {
reg.checkPassword(username, password);
} catch (PasswordCheckFailedException e) {
throw new OAuth20MediatorException("User doesn't exist or the
password doesn't match.", e);
} catch (CustomRegistryException e) {
throw new OAuth20MediatorException("Cannot validate resource owner.", e);
} catch (RemoteException e) {
throw new OAuth20MediatorException("Cannot validate resource owner.", e);
}
}
LOG.exiting(CLASS, methodName);
}
public void mediateTokenException(AttributeList attributeList,
OAuthException exception)
throws OAuth20MediatorException {
final String methodName = "mediateTokenException";
LOG.entering(CLASS, methodName, new Object[] {attributeList, exception});
if("password".equals(attributeList.getAttributeValueByName("grant_type"))) {
// clear sensitive data
attributeList.setAttribute("access_token",
OAuth20Constants.ATTRTYPE_RESPONSE_ATTRIBUTE,
new String[0]);
attributeList.setAttribute("refresh_token",
OAuth20Constants.ATTRTYPE_RESPONSE_ATTRIBUTE,
new String[0]);
}
LOG.exiting(CLASS, methodName);
}
}