Vous pouvez développer un fournisseur JACC (Java
Authorization Contract for Containers) afin de disposer de
décisions d'autorisation personnalisées pour les applications
Java™ Platform, Enterprise
Edition (J2EE), en implémentant l'interface
com.ibm.wsspi.security.authorization.jacc.ProviderService
qui est fournie sur le serveur Liberty.
Avant de commencer
Par défaut, le chargement du module d'application est reporté jusqu'à ce que la demande sur l'application soit traitée. Toutefois, la contrainte de sécurité de tout le module dans
l'application doit être traitée avant que l'application soit prête à être traitée. Le chargement du module différé
doit être désactivé. La procédure suivante indique comment effectuer
cette désactivation :
- Pour le conteneur Web :
Dans le fichier
server.xml,
les éléments suivants doivent être définis :
<webContainer deferServletLoad="false"/>
- Pour le conteneur d'EJB :
Dans le fichier
server.xml, la propriété suivante doit être définie :
<ejbContainer startEJBsAtAppStart="true"/>
Remarque : Si les éléments précédents ne sont pas définis, les informations de contrainte de sécurité complètes risquent de ne pas pouvoir être propagées au fournisseur JACC tiers au démarrage du serveur. Par conséquent, il est possible que la décision d'autorisation correcte ne soit pas mise en oeuvre par le fournisseur JACC tiers.
Pourquoi et quand exécuter cette tâche
La spécification
Java
Authorization Contract for Containers,
JSR 115, définit une interface pour les fournisseurs
d'autorisation. Sur le serveur Liberty, vous devez packager votre fournisseur JACC
en tant que fonction utilisateur. Votre fonction doit
implémenter l'interface
com.ibm.wsspi.security.authorization.jacc.ProviderService.
Procédure
- Créez un composant OSGi qui fournit un
service qui implémente l'interface com.ibm.wsspi.security.authorization.jacc.ProviderService.
L'interface ProviderService définit deux méthodes : la méthode getPolicy que l'environnement d'exécution Liberty appelle pour extraire une instance de votre
classe Policy qui implémente la classe abstraite java.security.Policy ; et la méthode getPolicyConfigFactory, que l'environnement d'exécution Liberty
appelle pour extraire une instance de votre classe PolicyConfigurationFactory qui implémente la classe abstraite javax.security.jacc.PolicyConfigurationFactory.
L'exemple suivant utilise les annotations de services déclaratifs
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) {}
}
- Packagez le composant dans un bundle OSGi qui fait partie de
votre fonction, avec votre fournisseur JACC.
- Vérifiez que votre fonction inclut le contenu de sous-système OSGi :
com.ibm.ws.javaee.jacc.1.5; version="[1,1.0.100)"; location:="dev/api/spec/".
- Une fois la fonction installée dans l'emplacement
d'extension de produit utilisateur, configurez le fichier
server.xml avec le nom de la fonction. Exemple :
<featureManager>
...
<feature>usr:myJaccProvider</feature>
</featureManager>