Chapitre 16. Modules de connexion
16.1. Utilisation des modules
16.1.1. Empilage des mots de passe
password-stacking
défini à useFirstPass
. Si un module précédemment configuré pour l'empilage de mots de passe a authentifié l'utilisateur, tous les autres modules d'empilage tiendront compte de l'utilisateur authentifié et ne feront que de fournir des rôles pour l'étape de l'autorisation.
password-stacking
est définie à useFirstPass
, ce module commence par chercher le nom d'utilisateur et le mot de passe en commun sous les noms de propriété javax.security.auth.login.name et javax.security.auth.login.password respectivement dans la mappe d'états partagés du module de connexion.
Note
Exemple 16.1. Exemple d'empilage de mots de passe
/subsystem=security/security-domain=pwdStack/authentication=classic/login-module=Ldap:add( \ code=Ldap, \ flag=required, \ module-options=[ \ ("password-stacking"=>"useFirstPass"), \ ... Ldap login module configuration ]) /subsystem=security/security-domain=pwdStack/authentication=classic/login-module=Database:add( \ code=Database, \ flag=required, \ module-options=[ \ ("password-stacking"=>"useFirstPass"), \ ... Database login module configuration ])
16.1.2. Hachage de mots de passe
Important
Exemple 16.2. Hachage de mots de passe
nobody
et qui contient des hachages codé based64, SHA-256, des mots de passe dans un fichier usersb64.properties
. Le fichier usersb64.properties
fait partie du chemin de classe de déploiement.
/subsystem=security/security-domain=testUsersRoles:add /subsystem=security/security-domain=testUsersRoles/authentication=classic:add /subsystem=security/security-domain=testUsersRoles/authentication=classic/login-module=UsersRoles:add( \ code=UsersRoles, \ flag=required, \ module-options=[ \ ("usersProperties"=>"usersb64.properties"), \ ("rolesProperties"=>"test-users-roles.properties"), \ ("unauthenticatedIdentity"=>"nobody"), \ ("hashAlgorithm"=>"SHA-256"), \ ("hashEncoding"=>"base64") \ ])
- hashAlgorithm
- Nom de l'algorithme
java.security.MessageDigest
à utiliser pour hacher le mot de passe. Il n'y a aucune valeur par défaut, donc cette option doit être spécifiée pour permettre le hachage. Les valeurs typiques sont leSHA-256
,SHA-1
etMD5
. - hashEncoding
- String qui spécifie un des trois types d'encodage :
base64
,hex
ourfc2617
. La valeur par défaut estbase64
. - hashCharset
- Groupe de caractères utilisé pour convertir le mot de passe en texte clair en tableau d'octets. L'encodage par défaut de la plateforme correspond à la valeur par défaut.
- hashUserPassword
- Indique que l'algorithme de hachage doit s'appliquer au mot de passe que l'utilisateur soumet. Le hachage de mot de passe est comparée à la valeur du module de connexion, ce qui est censé être un hachage du mot de passe. La valeur par défaut est
true
. - hashStorePassword
- Indique que l'algorithme de hachage doit s'appliquer au mot de passe stocké sur le serveur. Il est utilisé pour l'authentification digest, lorsque l'utilisateur soumet un hachage du mot de passe utilisateur ainsi qu'un jeton spécifique à la demande du serveur pour comparaison. L'algorithme de hachage (pour digest, il s'agit de
rfc2617
) sert à calculer un hachage du côté serveur, qui doit correspondre à la valeur de hachage envoyée par le client.
org.jboss.security.auth.spi.Util
fournit une méthode d'assistance statique qui servira au hachage de mot de passe à l'aide du codage spécifié. L'exemple suivant génère un mot de passe MD5 haché codé en base64.
String hashedPassword = Util.createPasswordHash("SHA-256", Util.BASE64_ENCODING, null, null, "password");
password
- est acheminé dans la fonction digest OpenSSL, puis dans une autre fonction OpenSSL pour se convertir au format codé en base 64.
echo -n password | openssl dgst -sha256 -binary | openssl base64
XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=
. Cette valeur devra être stockée dans le fichier de propriété des utilisateurs, dans le domaine de sécurité - usersb64.properties
- comme dans l'exemple ci-dessus.
16.1.3. Identité non authentifée
unauthenticatedIdentity
est une option de configuration de module de login qui attribue une identité spécifique (invité, par exemple) aux demandes qui sont faites sans aucune information d'authentification associée. Ceci peut être utilisé pour permettre à des servlets non protégés d'appeler des méthodes ne nécessitant pas un rôle spécifique sur EJB. Un tel principal n'a aucun rôle associé et ne peut donc accéder qu'à des EJB non sécurisés ou à des méthodes EJB associées à la contrainte de permission non vérifiée.
- unauthenticatedIdentity: définit le nom de principal qui doit être assigné aux requêtes ne contenant pas d'informations d'authentification.
16.1.4. Module de connexion Ldap
Ldap
est une implémentation du LoginModule
qui authentifie sur le serveur LDAP (Lightweight Directory Access Protocol). Utiliser le module de connexion Ldap
si votre nom d'utilisateur et vos identifiants sont stockés dans une serveur LDAP accessible en utilisant un fournisseur LDAP JNDI (Java Naming and Directory Interface).
Note
AdvancedLdap
avec le module de connexion SPNEGO ou bien le login de connexion AdvancedLdap
seul.
- Nom distinctif (DN)
- Avec le protocole LDAP (Lightweight Directory Access Protocol), le nom unique identifie de manière unique un objet dans un répertoire. Chaque nom distinctif doit avoir un nom et un emplacement uniques distincts de tout autre objet, ce qui est réalisé à l'aide d'un certain nombre de paires attribut / valeur (AVPs). Les AVP définissent les informations telles que des noms communs, unité d'organisation, entre autres. La combinaison de ces résultats de valeurs résultent en une chaîne unique, requise par le protocole LDAP.
Note
- java.naming.factory.initial
- Nom de classe d'implémentation
InitialContextFactory
. A comme valeur par défaut celle de l'implémentaion du fournisseur Sun LDAPcom.sun.jndi.ldap.LdapCtxFactory
. - java.naming.provider.url
- URL LDAP pour le serveur LDAP.
- java.naming.security.authentication
- Niveau de protocole de sécurité à utiliser. Les valeurs suivantes sont disponibles
none
,simple
, etstrong
. Si la propriété n'est pas définie, le comportement sera dicté par le fournisseur de services. - java.naming.security.protocol
- Le protocole de transport à utiliser pour un accès sécurisé. Définir cette option de configuration au type de fournisseur de service (comme par exemple, SSL). Si la propriété n'est pas définie, le comportement sera déterminé par le fournisseur de services.
- java.naming.security.principal
- Indique l'identité du principal permettant d'authentifier l'appelant vers le service. Il est construit à partir des autres propriétés décrites ci-dessous.
- java.naming.security.credentials
- Indique les identifiants du principal permettant d'authentifier l'appelant vers le service. Les identifiants peuvent prendre la forme d'un mot de passe haché, un mot de passe en texte clair, une clé ou un certificat. Si la propriété n'est pas définie, le comportement sera déterminé par le fournisseur de services.
Note
true
InitialLdapContext
avec un environnement composé de propriétés JNDI LDAP décrites précédemment dans cette section.
InitialLdapContext
est créée), les rôles de l'utilisateur sont vérifiés par le biais d'une recherche sur l'emplacement de rolesCtxDN
avec des attributs de recherche définis aux valeurs roleAttributeName et uidAttributeName. Les noms de rôle sont obtenus par invocation de la méthode toString
sur les attributs de rôle sur le groupe de résultat de la recherche.
Exemple 16.3. Domaine de sécurité du module de connexion LDAP
/subsystem=security/security-domain=testLDAP:add(cache-type=default) /subsystem=security/security-domain=testLDAP/authentication=classic:add /subsystem=security/security-domain=testLDAP/authentication=classic/login-module=Ldap:add( \ code=Ldap, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org:1389/"), \ ("java.naming.security.authentication"=>"simple"), \ ("principalDNPrefix"=>"uid="), \ ("principalDNSuffix"=>",ou=People,dc=jboss,dc=org"), \ ("rolesCtxDN"=>"ou=Roles,dc=jboss,dc=org"), \ ("uidAttributeID"=>"member"), \ ("matchOnUserDN"=>true), \ ("roleAttributeID"=>"cn"), \ ("roleAttributeIsDN"=>false) \ ])
java.naming.factory.initial
, java.naming.factory.url
et java.naming.security
dans la configuration du domaine de sécurité testLDAP indique les conditions suivantes :
- L'implémentation du fournisseur JNDI LDAP sera utilisée
- Le serveur LDAP se situe sur l'hôte
ldaphost.jboss.org
sur le port 1389 - La méthode simple d'authentification LDAP sera utilisée pour se connecter au serveur LDAP.
jsmith
mappe au uid=jsmith,ou=People,dc=jboss,dc=org
.
Note
userPassword
de l'entrée d'utilisateur (theduke
dans cet exemple). La plupart des serveurs LDAP fonctionnent de cette manière, mais si votre serveur LDAP gère l'authentification différemment, vous devez vous assurer que LDAP soit configuré selon vos besoins d'environnement de production.
rolesCtxDN
dont le uidAttributeID correspond à l'utilisateur. Si matchOnUserDN a la valeur true, la recherche s'appuiera sur le nom distinctif complet de l'utilisateur. Sinon, la recherche s'appuiera sur le nom d'utilisateur saisi. Dans cet exemple, la recherche est sous ou=Roles,dc=jboss,dc=org
pour toutes les entrées qui ont un attribut de membre
égal à uid=jsmith,ou=People,dc=jboss,dc=org
. La recherche permettait de situer cn=JBossAdmin
sous la rubrique rôles.
cn
. La valeur renvoyée est JBossAdmin
, donc l'utilisateur jsmith
reçoit le rôle JBossAdmin
.
- LDAP LDIF (Data Interchange Format)
- Format en texte brut utilisé pour représenter le contenu du répertoire LDAP et mettre à jour les requêtes. Le contenu du répertoire est représenté comme un enregistrement pour chaque requête d'objet ou de mise à jour. Le contenu consiste à ajouter, modifier, supprimer et renommer des requêtes.
Exemple 16.4. Exemple de fichier LDIF
dn: dc=jboss,dc=org objectclass: top objectclass: dcObject objectclass: organization dc: jboss o: JBoss dn: ou=People,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jsmith,ou=People,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person uid: jsmith cn: John sn: Smith userPassword: theduke dn: ou=Roles,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: Roles dn: cn=JBossAdmin,ou=Roles,dc=jboss,dc=org objectclass: top objectclass: groupOfNames cn: JBossAdmin member: uid=jsmith,ou=People,dc=jboss,dc=org description: the JBossAdmin group
16.1.5. Module de connexion LdapExtended
- Nom distinctif (DN)
- Avec le protocole LDAP (Lightweight Directory Access Protocol), le nom unique identifie de manière unique un objet dans un répertoire. Chaque nom distinctif doit avoir un nom et un emplacement uniques distincts de tout autre objet, ce qui est réalisé à l'aide d'un certain nombre de paires attribut / valeur (AVPs). Les AVP définissent les informations telles que des noms communs, unité d'organisation, entre autres. La combinaison de ces résultats de valeurs résultent en une chaîne unique, requise par le protocole LDAP.
org.jboss.security.auth.spi.LdapExtLoginModule)
recherche l'utilisateur à relier, ainsi que les rôles associés, en vue d'effectuer l'authentification. La requête récursive des rôles suit les DN pour naviguer à travers une structure de rôles hiérarchiques.
- Context.INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial"
- Context.SECURITY_PROTOCOL = "java.naming.security.protocol"
- Context.PROVIDER_URL = "java.naming.provider.url"
- Context.SECURITY_AUTHENTICATION = "java.naming.security.authentication"
- Context.REFERRAL = "java.naming.referral"
- La liaison initiale de serveur LDAP est authentfiée par l'intermédiaire des propriétés bindDN et bindCredential. Le bindDN est un utilisateur ayant les permissions de chercher les utilisateurs et les rôles à la fois dans les arborescences baseCtxDN et rolesCtxDN. Le DN d'utilisateur ou user DN pour s'authentifier est trouvé grâce au filtre spécifié dans la propriété baseFilter.
- Le DN d'utilisateur userDN qui en résulte est authentifié par la liaison au serveur LDAP en utilisant le userDN comme environnement de InitialLdapContext. Context.SECURITY_PRINCIPAL. La propriété Context.SECURITY_CREDENTIALS est définie avec le mot de passe String obtenu par le gestionnaire de rappel.
- Si cela réussit, les rôles d'utilisateur associés seront interrogés par l'intermédiaire des options rolesCtxDN, roleAttributeID, roleAttributeIsDN, roleNameAttributeID, et roleFilter.

Figure 16.1. Exemple de structure LDAP
Exemple 16.5. Exemple 2 de configuration LDAP
version: 1 dn: o=example2,dc=jboss,dc=org objectClass: top objectClass: organization o: example2 dn: ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: judke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke2 employeeNumber: judke2-123 sn: Duke2 uid: jduke2 userPassword:: dGhlZHVrZTI= dn: ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke dn: uid=jduke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org memberOf: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org uid: jduke2 dn: cn=Echo,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the echo role member: uid=jduke,ou=People,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke description: the duke role member: uid=jduke,ou=People,o=example2,dc=jboss,dc=org dn: cn=Echo2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo2 description: the Echo2 role member: uid=jduke2,ou=People,dc=jboss,dc=org dn: cn=TheDuke2,ou=Roles,o=example2,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke2 description: the duke2 role member: uid=jduke2,ou=People,o=example2,dc=jboss,dc=org dn: cn=JBossAdmin,ou=Roles,o=example2,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: JBossAdmin description: the JBossAdmin group member: uid=jduke,ou=People,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample2/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example2,dc=jboss,dc=org"), \ ("baseFilter"=>"(uid={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example2,dc=jboss,dc=org"), \ ("roleFilter"=>"(uid={0})"), \ ("roleAttributeIsDN"=>"true"), \ ("roleAttributeID"=>"memberOf"), \ ("roleNameAttributeID"=>"cn") \ ])
Exemple 16.6. Exemple 3 de configuration LDAP
dn: o=example3,dc=jboss,dc=org objectclass: top objectclass: organization o: example3 dn: ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example3,dc=jboss,dc=org objectclass: top objectclass: uidObject objectclass: person objectClass: inetOrgPerson uid: jduke employeeNumber: judke-123 cn: Java Duke sn: Duke userPassword: theduke dn: ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: uid=jduke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupUserEx memberOf: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org memberOf: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org uid: jduke dn: cn=Echo,ou=Roles,o=example3,dc=jboss,dc=org objectClass: top objectClass: groupOfNames cn: Echo description: the JBossAdmin group member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org dn: cn=TheDuke,ou=Roles,o=example3,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: TheDuke member: uid=jduke,ou=People,o=example3,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample3/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example3,dc=jboss,dc=org"), \ ("baseFilter"=>"(cn={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example3,dc=jboss,dc=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleAttributeID"=>"cn") \ ])
Exemple 16.7. Exemple 4 de configuration LDAP
dn: o=example4,dc=jboss,dc=org objectclass: top objectclass: organization o: example4 dn: ou=People,o=example4,dc=jboss,dc=org objectclass: top objectclass: organizationalUnit ou: People dn: uid=jduke,ou=People,o=example4,dc=jboss,dc=org objectClass: top objectClass: uidObject objectClass: person objectClass: inetOrgPerson cn: Java Duke employeeNumber: jduke-123 sn: Duke uid: jduke userPassword:: dGhlZHVrZQ== dn: ou=Roles,o=example4,dc=jboss,dc=org objectClass: top objectClass: organizationalUnit ou: Roles dn: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG1 member: cn=empty dn: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG2 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org dn: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: RG3 member: cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R1,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R1 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R2,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R2 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R3,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R3 member: cn=RG2,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R4,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R4 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org dn: cn=R5,ou=Roles,o=example4,dc=jboss,dc=org objectClass: groupOfNames objectClass: top cn: R5 member: cn=RG3,cn=RG1,ou=Roles,o=example4,dc=jboss,dc=org member: uid=jduke,ou=People,o=example4,dc=jboss,dc=org
/subsystem=security/security-domain=testLdapExample4/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.factory.initial"=>"com.sun.jndi.ldap.LdapCtxFactory"), \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.security.authentication"=>"simple"), \ ("bindDN"=>"cn=Root,dc=jboss,dc=org"), \ ("bindCredential"=>"secret1"), \ ("baseCtxDN"=>"ou=People,o=example4,dc=jboss,dc=org"), \ ("baseFilter"=>"(cn={0})"), \ ("rolesCtxDN"=>"ou=Roles,o=example4,dc=jboss,dc=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleRecursion"=>"1"), \ ("roleAttributeID"=>"memberOf") \ ])
Exemple 16.8. Configuration Active Directory par défaut
/subsystem=security/security-domain=AD_Default/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("bindDN"=>"JBOSS\searchuser"), \ ("bindCredential"=>"password"), \ ("baseCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("baseFilter"=>"(sAMAccountName={0})"), \ ("rolesCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("roleFilter"=>"(sAMAccountName={0})"), \ ("roleAttributeID"=>"memberOf"), \ ("roleAttributeIsDN"=>"true"), \ ("roleNameAttributeID"=>"cn"), \ ("searchScope"=>"ONELEVEL_SCOPE"), \ ("allowEmptyPasswords"=>"false") \ ])
Exemple 16.9. Configuration Active Directory de rôles récursifs
/subsystem=security/security-domain=AD_Recursive/authentication=classic/login-module=LdapExtended:add( \ code=LdapExtended, \ flag=required, \ module-options=[ \ ("java.naming.provider.url"=>"ldap://ldaphost.jboss.org"), \ ("java.naming.referral"=>"follow"), \ ("bindDN"=>"JBOSS\searchuser"), \ ("bindCredential"=>"password"), \ ("baseCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("baseFilter"=>"(sAMAccountName={0})"), \ ("rolesCtxDN"=>"CN=Users,DC=jboss,DC=org"), \ ("roleFilter"=>"(member={1})"), \ ("roleAttributeID"=>"cn"), \ ("roleAttributeIsDN"=>"false"), \ ("roleRecursion"=>"2"), \ ("searchScope"=>"ONELEVEL_SCOPE"), \ ("allowEmptyPasswords"=>"false") \ ])
16.1.6. Module de connexion UserRoles
UsersRoles
est un module de connexion simple qui prend en charge plusieurs utilisateurs et des rôles d'utilisateur chargés à partir de fichiers de propriétés Java. Le nom de fichier de mappage de nom-d'utilisateur-à-mot-de-passe par défaut est users.properties
et le nom du fichier de mappage de nom-d'utilisateur-à-rôles par défaut est roles.properties
.
WEB-INF/classes
dans l'archive WAR
), ou dans n'importe quel répertoire sur le chemin de classse du serveur. L'objectif principal de ce module de connexion est de tester facilement les paramètres de sécurité d'utilisateurs et de rôles multiples à l'aide de fichiers déployés avec l'application.
Exemple 16.10. Module de connexion UserRoles
/subsystem=security/security-domain=ejb3-sampleapp/authentication=classic/login-module=UsersRoles:add( \ code=UsersRoles, \ flag=required, \ module-options=[ \ ("usersProperties"=>"ejb3-sampleapp-users.properties"), \ ("rolesProperties"=>"ejb3-sampleapp-roles.properties") \ ])
ejb3-sampleapp-users.properties
utilise un format username=password
pour chaque entrée d'utilisateur sur ligne séparée :
username1=password1 username2=password2 ...
ejb3-sampleapp-roles.properties
référencé dans Exemple 16.10, « Module de connexion UserRoles » utilise le modèle username=role1,role2,
avec une valeur de nom de groupe en option. Par exemple :
username1=role1,role2,... username1.RoleGroup1=role3,role4,... username2=role1,role3,...
ejb3-sampleapp-roles.properties
est utilisé pour assigner les rôles de nom d'utilisateur à un groupe de rôles de groupe nommé particulier où la portion XXX
du nom de propriété est le nom de groupe. La forme user name=... est une abbréviation de user name.Roles=..., où le nom de groupe Roles
correspond au nom standard auquel JBossAuthorizationManager
s'attend pour contenir les rôles qui définissent les permissions utilisateur.
jduke
:
jduke=TheDuke,AnimatedCharacter jduke.Roles=TheDuke,AnimatedCharacter
16.1.7. Module de connexion Database
Database
est un JDBC (Java Database Connectivity-based) qui supporte l'authentification et le mappage des rôles. Utiliser ce module de connexion si vous avez vos nom d'utilisateur, mot de passe et information de rôle stockés dans une case de données relationnelle.
Note
Database
est basé sur deux tableaux logiques :
Table Principals(PrincipalID text, Password text) Table Roles(PrincipalID text, Role text, RoleGroup text)
Principals
fait correspondre l'utilisateur PrincipalID
au nom de passe valide et le tableau Roles
fait correspondre l'utilisateur PrincipalID
à ses groupes de rôles. Les rôles utilisés pour les permissions utilisateur doivent se trouver dans des lignes ayant pour valeur de colonne RoleGroup
correspondant à Roles
.
java.sql.ResultSet
ait la même structure logique que les tableaux Principals
et Roles
décrits précédemment. Les noms des tables et des colonnes ne sont pas pertinents car les résultats sont accessibles selon l'index de colonne.
Principals
et Roles
, déjà déclarés. Les énoncés suivants remplissent les tableaux avec les données suivantes :
PrincipalID
java
avec un mot de passe (Password
) correspondant àechoman
dans le tableauPrincipals
PrincipalID
java
ayant un rôle nomméEcho
dansRoles
RoleGroup
dans le tableauRoles
PrincipalID
java
ayant un rôle nommécaller_java
dansCallerPrincipal
RoleGroup
dans le tableauRoles
INSERT INTO Principals VALUES('java', 'echoman') INSERT INTO Roles VALUES('java', 'Echo', 'Roles') INSERT INTO Roles VALUES('java', 'caller_java', 'CallerPrincipal')
Database login module
:
CREATE TABLE Users(username VARCHAR(64) PRIMARY KEY, passwd VARCHAR(64)) CREATE TABLE UserRoles(username VARCHAR(64), role VARCHAR(32))
/subsystem=security/security-domain=testDB/authentication=classic/login-module=Database:add( \ code=Database, \ flag=required, \ module-options=[ \ ("dsJndiName"=>"java:/MyDatabaseDS"), \ ("principalsQuery"=>"select passwd from Users where username=?"), \ ("rolesQuery"=>"select role, 'Roles' from UserRoles where username=?") \ ])
16.1.8. Module de connexion Certificate
Certificate
authentifie les utilisateurs sur la base de certificats X509. L'authentification en web tier CLIENT-CERT
est un cas d'utilisation typique de ce module de connexion.
CertRolesLoginModule
et DatabaseCertLoginModule
étendent le comportement pour pouvoir obtenir les rôles d'autorisation soit du fichier de propriétés, soit de la base de données.
Certificate
, voir Section A.1, « Modules d'authentification inclus ».
Certificate
requiert un KeyStore
pour effectuer la validation utilisateur. Elle s'obtient à partir de la configuration JSSE d'un domaine de sécurité lié, comme le montre le fragment de configuration ci-dessous :
/subsystem=security/security-domain=trust-domain:add /subsystem=security/security-domain=trust-domain/jsse=classic:add( \ truststore={ \ password=>pass1234, \ url=>/home/jbosseap/trusted-clients.jks \ }) /subsystem=security/security-domain=testCert:add /subsystem=security/security-domain=testCert/authentication=classic:add /subsystem=security/security-domain=testCert/authentication=classic/login-module=Certificate:add( \ code=Certificate, \ flag=required, \ module-options=[ \ ("securityDomain"=>"trust-domain"), \ ])
Procédure 16.1. Sécuriser les applications web par des certificats et des autorisations basées rôle
user-app.war
, en utilisant les certificats client et les autorisations basées rôle. Dans cet exemple, le module de connexion CertificateRoles
est utilisé pour l'authentification et l'autorisation. Les trusted-clients.keystore
et app-roles.properties
requiérent une entrée qui mappe le principal associé au certificat du client.
Déclarer les ressources et les rôles
Modifierweb.xml
pour déclarer les ressources à sécuriser avec les rôles autorisés et le domaine de sécurité à utiliser pour l'authentification et l'autorisation.<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <security-constraint> <web-resource-collection> <web-resource-name>Protect App</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>Admin</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>CLIENT-CERT</auth-method> <realm-name>Secured area</realm-name> </login-config> <security-role> <role-name>Admin</role-name> </security-role> </web-app>
Spécifier un domaine de sécurité
Dans le fichierjboss-web.xml
, indiquer le domaine de sécurité requis.<jboss-web> <security-domain>app-sec-domain</security-domain> </jboss-web>
Configurer le module de sécurité
Définir la configuration du module de connexion pour le domaineapp-sec-domain
que vous venez d'indiquer par le biais du CLI.[ /subsystem=security/security-domain=trust-domain:add /subsystem=security/security-domain=trust-domain/jsse=classic:add( \ truststore={ \ password=>pass1234, \ url=>/home/jbosseap/trusted-clients.jks \ }) /subsystem=security/security-domain=app-sec-domain:add /subsystem=security/security-domain=app-sec-domain/authentication=classic:add /subsystem=security/security-domain=app-sec-domain/authentication=classic/login-module=CertificateRoles:add( \ code=CertificateRoles, \ flag=required, \ module-options=[ \ ("securityDomain"=>"trust-domain"), \ ("rolesProperties"=>"app-roles.properties") \ ])
Exemple 16.11. Exemple de certificat
[conf]$ keytool -printcert -file valid-client-cert.crt Owner: CN=valid-client, OU=Security QE, OU=JBoss, O=Red Hat, C=CZ Issuer: CN=EAP Certification Authority, OU=Security QE, OU=JBoss, O=Red Hat, C=CZ Serial number: 2 Valid from: Mon Mar 24 18:21:55 CET 2014 until: Tue Mar 24 18:21:55 CET 2015 Certificate fingerprints: MD5: 0C:54:AE:6E:29:ED:E4:EF:46:B5:14:30:F2:E0:2A:CB SHA1: D6:FB:19:E7:11:28:6C:DE:01:F2:92:2F:22:EF:BB:5D:BF:73:25:3D SHA256: CD:B7:B1:72:A3:02:42:55:A3:1C:30:E1:A6:F0:20:B0:2C:0F:23:4F:7A:8E:2F:2D:FA:AF:55:3E:A7:9B:2B:F4 Signature algorithm name: SHA1withRSA Version: 3
trusted-clients.keystore
exige que le certificat Exemple 16.11, « Exemple de certificat » soit stocké avec un alias CN=valid-client, OU=Security QE, OU=JBoss, O=Red Hat, C=CZ
. Les app-roles.properties
doivent avoir les mêmes saisies. Comme le DN contient des caractères qui sont normalement considérés comme des délimiteurs, vous devrez utiliser ('\
') pour les carctères problématiques comme illustré ci-dessous.
# A sample app-roles.properties file CN\=valid-client,\ OU\=Security\ QE,\ OU\=JBoss,\ O\=Red\ Hat,\ C\=CZ
16.1.9. Module de connexion d'identité
Identity
est un simple module de connexion qui associe un nom d'utilisateur codé en dur à tout subject authentifié dans le module. Il crée une instance SimplePrincipal
qui utilise le nom spécifié par l'option principal
.
Note
jduke
et assigne les noms de rôle TheDuke
, et AnimatedCharacter
:.
/subsystem=security/security-domain=testIdentity:add /subsystem=security/security-domain=testIdentity/authentication=classic:add /subsystem=security/security-domain=testIdentity/authentication=classic/login-module=Identity:add( \ code=Identity, \ flag=required, \ module-options=[ \ ("principal"=>"jduke"), \ ("roles"=>"TheDuke,AnimatedCharacter") \ ])
16.1.10. Module de connexion RunAs
RunAs
est un module d'assitance qui pousse le rôle run as
dans la pile pour le durée de la phase de connexion de l'authentification, puis qui produit le rôle run as
de la pile lors de la phase de validation ou de suppression.
RunAs
doit être configuré avant que les modules de connexion qui ont besoin d'une rôle run as
soient mis en place.
16.1.10.1. Création de RunAsIdentity
javax.security.auth.Subject
ou par une instance org.jboss.security.RunAsIdentity
. Ces deux classes stockent un ou deux principaux qui représentent l'identité et la liste des rôles que possède l'identité. Dans le cas de la classe javax.security.auth.Subject
, une liste d'informations d'identification est également stockée.
ejb-jar.xml
, vous spécifiez un ou plusieurs rôles qu'un utilisateur doit avoir pour accéder aux différentes méthodes EJB. Une comparaison de ces listes révèle si l'utilisateur possède un des rôles nécessaires pour accéder à la méthode EJB.
Exemple 16.12. Création de org.jboss.security.RunAsIdentity
ejb-jar.xml
, vous spécifiez un élément <security-identity> avec un rôle <run-as> défini comme un enfant de l'élément <session>.
<session> ... <security-identity> <run-as> <role-name>Admin</role-name> </run-as> </security-identity> ... </session>
Admin
doit être créé.
Admin
, vous devez définir un élément <run-as-principal>
dans le fichier jboss-ejb3.xml
.
<jboss:ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns:s="urn:security:1.1" version="3.1" impl-version="2.0"> <assembly-descriptor> <s:security> <ejb-name>WhoAmIBean</ejb-name> <s:run-as-principal>John</s:run-as-principal> </s:security> </assembly-descriptor> </jboss:ejb-jar>
<security-identity>
qui se trouve à la fois dans ejb-jar.xml
et dans l'élément <security>
des fichiers jboss-ejb3.xml
sont traités en cours de déploiement. Le nom de rôle <run-as>
et le nom <run-as-principal>
sont alors stockés dans la classe org.jboss.metadata.ejb.spec.SecurityIdentityMetaData
.
Exemple 16.13. Assigner plusieurs rôles à une RunAsIdentity
<assembly-descriptor>
du descripteur de déploiement jboss-ejb3.xml
.
<jboss:ejb-jar xmlns:sr="urn:security-role" ...> <assembly-descriptor> ... <sr:security-role> <sr:role-name>Support</sr:role-name> <sr:principal-name>John</sr:principal-name> <sr:principal-name>Jill</sr:principal-name> <sr:principal-name>Tony</sr:principal-name> </sr:security-role> </assembly-descriptor> </jboss:ejb-jar>
<run-as-principal>
de John
a été créé. La configuration dans cet exemple étend le rôle Admin
en ajoutant le rôle Support
. Le nouveau rôle contient des principaux supplémentaires, y compris le principal John
de départ.
<security-role>
qui se trouve à la fois dans les fichiers ejb-jar.xml
et jboss-ejb3.xml
sont traités en cours de déploiement. Les données de <role-name>
et de <principal-name>
sont alors stockées dans la classe org.jboss.metadata.ejb.spec.SecurityIdentityMetaData
.
16.1.11. Module de connexion Client
Client
(org.jboss.security.ClientLoginModule
) est une implémentation du LoginModule
utilisable par les clients JBoss quand ils souhaitenet établir l'identité et les identifiants d'un appelant. Cela crée un nouveau SecurityContext
, lui assigne un principal et des informations d'identification, et assigne le SecurityContext
au ThreadLocal
.
client
est le seul mécanisme pris en charge pour qu'un client puisse établir qui est l'appelant du thread en cours. Les applications clientes autonomes et les environnements de serveurs (agissant en tant que clients JBoss EJB où l'environnement de sécurité n'a pas été configuré pour utiliser le sous-système de sécurité EAP de façon transparente) doivent utiliser le module de connexion Client
.
Client
.
16.1.12. Module de connexion SPNEGO
SPNEGO
(org.jboss.security.negotiation.spnego.SPNEGOLoginModule
) est une implémentation de LoginModule
qui établit l'identité de l'appelant et les informations d'identification avec un KDC. Le module implémente SPNEGO (mécanisme de négociation GSSAPI simple et protégé) et fait partie du projet JBoss Negotiation. Cette authentification peut être utilisée dans la configuration chaînée avec le module de connexion AdvancedLdap
pour permettre la coopération avec un serveur LDAP.
SPNEGO
ou AdvancedLdap
dans votre projet, vous devez ajouter manuellement la dépendance en éditant le fichier de descripteur de déploiement META-INF/jboss-déploiement-structure.xml
.
Exemple 16.14. Ajouter le module JBoss Negociation en tant que dépendance.
<jboss-deployment-structure> <deployment> <dependencies> <module name="org.jboss.security.negotiation" /> </dependencies> </deployment> </jboss-deployment-structure>
16.1.13. Module de connexion RoleMapping
RoleMapping
supporte les rôles de mappage qui résultent en fin de processus d'authentification, à un ou plusiurs rôles déclaratifs. Ainsi, si le processus d'authentification a déterminé que l'utilisateur 'A' a les rôles "ldapAdmin" et "testAdmin"et que le rôle déclaratif défini dans le fichier web.xml
ou le fichier ejb-jar.xml
est admin
, alors ce module de connexion mappera les rôles admin
à l'utilisateur A
.
RoleMapping
, voir Section A.1, « Modules d'authentification inclus ».
RoleMapping
doit être défini comme un module optionnel de configuration de module de connexion car il modifie le mappage des rôles déjà mappés.
Exemple 16.15. Définir les rôles mappés
/subsystem=security/security-domain=test-domain-2/:add /subsystem=security/security-domain=test-domain-2/authentication=classic:add /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test-2-lm/:add(\ flag=required,\ code=UsersRoles,\ module-options=[("usersProperties"=>"users.properties"),("rolesProperties"=>"roles.properties")]\ ) /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test2-map/:add(\ flag=optional,\ code=RoleMapping,\ module-options=[("rolesProperties"=>"rolesMapping-roles.properties")]\ )
Exemple 16.16. Méthode recommandée pour définir les rôles mappés
/subsystem=security/security-domain=test-domain-2/:add /subsystem=security/security-domain=test-domain-2/authentication=classic:add /subsystem=security/security-domain=test-domain-2/authentication=classic/login-module=test-2-lm/:add(\ flag=required,\ code=UsersRoles,\ module-options=[("usersProperties"=>"users.properties"),("rolesProperties"=>"roles.properties")]\ ) /subsystem=security/security-domain=test-domain-2/mapping=classic/mapping-module=test2-map/:add(\ code=PropertiesRoles,type=role,\ module-options=[("rolesProperties"=>"rolesMapping-roles.properties")]\ )
Exemple 16.17. Fichier de propriétés utilisé par un RoleMappingLoginModule
ldapAdmin=admin, testAdmin
ldapAdmin
, alors les rôles admin
et testAdmin
seront ajoutés ou se substitueront au sujet authentifié en fonction de la valeur de propriété replaceRole.
16.1.14. Option du module bindCredential
bindCredential
est utilisée pour stocker les identifiants pour le DN et peut être utilisée par plusieurs modules de mappage et de connexion. Il existe plusieurs méthodes d'obtention du mot de passse.
- Texte brut dans une commande CLI de gestion.
- The password for the
bindCredential
module may be provided in plaintext, in a management CLI command. For example:("bindCredential"=>"secret1")
. For security reasons, the password should be encrypted using the JBoss EAP vault mechanism. - Utiliser une commande externe.
- Pour obtenir le mot de passe à partir de la sortie d'une commande externe, utilisez le format
{EXT}...
où...
est la commande externe. La première ligne de la sortie de commande est utilisée comme mot de passe.Pour améliorer la performance, la variante{EXTC[:expiration_in_millis]}
met en cache le mot de passe pour un nombre de millisecondes spécifié. Par défaut, le mot de passe mis en cache n'expire pas. Si la valeur0
(zero) est spécifiée, les indentifiants mis en cache n'expirent pas.Ka varianteEXTC
n'est prise en charge que par le module de connexionLdapExtended
.
Exemple 16.18. Obtenir un mot de passe à partir d'une commande externe
{EXT}cat /mysecretpasswordfile
Exemple 16.19. Obtenir un mot de passe à partir d'un fichier externe et le mettre en cache pendant 500 millisecondes
{EXTC:500}cat /mysecretpasswordfile