您可以實作 Liberty 伺服器中提供的 com.ibm.wsspi.security.authorization.jacc.ProviderService 介面,將 JACC 提供者開發成具備 Java™ Platform Enterprise Edition (J2EE) 應用程式的自訂授權決策。
開始之前
依預設,應用程式模組載入會延遲,直到處理發給該應用程式的要求為止。不過,在準備好處理該應用程式之前,需要先處理應用程式中整個模組的安全限制。需要停用延遲的模組載入。以下顯示如何停用:
- 對於 WebContainer:
在
server.xml 檔中,需要設定下列元素:
<webContainer deferServletLoad="false"/>
- 對於 EJBContainer:
在
server.xml 檔中,需要設定下列內容:
<ejbContainer startEJBsAtAppStart="true"/>
註: 如果未設定前述的元素,一旦啟動伺服器,可能不會將完整的安全限制資訊延伸到協力廠商 JACC 提供者。如此一來,協力廠商 JACC 提供者可能不會施行正確的授權決策。
關於這項作業
Java Authorization Contract for Containers 規格 JSR 115 定義了授權提供者的介面。在 Liberty 伺服器中,必須將 JACC 提供者包裝成一項使用者特性。您的特性必須實作 com.ibm.wsspi.security.authorization.jacc.ProviderService 介面。
程序
- 建立 OSGi 元件,以提供用來實作 com.ibm.wsspi.security.authorization.jacc.ProviderService 介面的服務。
ProviderService 介面定義了兩種方法。一種是 getPolicy
方法,Liberty 執行時期會呼叫此方法,以擷取實作 java.security.Policy 抽象類別之 Policy 類別的實例。另一種是 getPolicyConfigFactory 方法,Liberty 執行時期會呼叫此方法,以擷取實作 javax.security.jacc.PolicyConfigurationFactory 抽象類別之 PolicyConfigurationFactory 類別的實例。
下列範例使用 OSGi 宣告式服務註釋:
package com.mycompany.jacc;
import com.mycompany.jacc.MyAuthConfigProvider;
import com.ibm.wsspi.security.authorization.jacc.ProviderService;
import java.security.Policy;
import java.util.Map;
import javax.security.jacc.PolicyConfigurationFactory;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
// The property value of javax.security.jacc.policy.provider which defines the implementation class of Policy and
// javax.security.jacc.PolicyConfigurationFactory.provider which defines the implementation class of PolicyConfigurationFactory, are required for propagating the properties to the Liberty runtime.
@Component(service = ProviderService.class,
immediate = true,
property = {
"javax.security.jacc.policy.provider=com.myco.jacc.MyPolicy",
"javax.security.jacc.PolicyConfigurationFactory.provider="
+ "com.myco.jacc.MyFactoryImpl"
}
)
public class MyJaccProviderService implements ProviderService {
Map<String, String> configProps;
// This method called by the Liberty runtime
// to get an instance of Policy class
@Override
public Policy getPolicy() {
return new myPolicy();
}
// This method called by the Liberty runtime
// to get an instance of PolicyConfigurationFactory class
@Override
public PolicyConfigurationFactory getPolicyConfigurationFactory() {
ClassLoader cl = null;
PolicyConfigurationFactory pcf = null;
System.setProperty(
"javax.security.jacc.PolicyConfigurationFactory.provider",
"com.myco.jacc.MyFactoryImpl");
try {
cl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(
this.getClass().getClassLoader());
pcf = PolicyConfigurationFactory.getPolicyConfigurationFactory();
} catch (Exception e) {
return null;
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
return pcf;
}
@Activate
protected void activate(ComponentContext cc) {
// Read provider config properties here if needed,
// then pass them to the Provider ctor.
// This example reads the properties from the OSGi
// component definition.
configProps = (Map<String, String>) cc.getProperties();
}
@Deactivate
protected void deactivate(ComponentContext cc) {}
}
- 將該元件與您的 JACC 提供者一起包裝成 OSGi 軟體組,成為您使用者特性的一部分。
- 確定您的特性包含 OSGi 子系統內容:com.ibm.ws.javaee.jacc.1.5; version="[1,1.0.100)"; location:="dev/api/spec/"。
- 將特性安裝到使用者產品延伸位置之後,利用特性名稱來配置 server.xml 檔。例如:
<featureManager>
...
<feature>usr:myJaccProvider</feature>
</featureManager>