Problème azure AD : comportement étrange entre création et update d'un user

Bonjour,
j’utilise le code suivant pour créer ou mettre un jour un utilisateur depuis un ad Azure.
Le problème c’est que ce soit avec
if (!Grant.exists(login, false) ou String userId = getUserIdIfExist(login);
le traitement considère dans le preLoadGrant l’utilisateur est toujours considéré comme existant ce qui n’est pas le cas.
Il passe donc dans le traitement de mise à jour updateUser mais là
if (!usr.select(uid)) retourne false et donc le traitement s’arrete si je met

’ String uid = getUserIdIfExist(login);
if (StringUtils.isEmpty(uid)){
return null;
}

alors au moment de bUserTools.getForUpdate(uid); il est en erreur.

Est ce que vous auriez une explication sur le fait que le traitement ne passe pas dans le createUser ?
Une fois le traitement terminée le user est crée mais il n’a pas de responsabilité ce qui est logique le traitement sort avant.
J’ai executé plusieurs fois le code en debug avec différents comptes avec toujours le même résultat.

Version :
[Platform]
Status=OK
Version=5.1.7
BuiltOn=2021-10-11 21:23
Git=release/06df144aad08d1dc84d135cbaa736e153d26a617
Encoding=UTF-8
EndpointIP=172.20.0.3
EndpointURL=http://4b2345910247:8080

package com.simplicite.commons.ladnext;

import com.simplicite.util.*;
import com.simplicite.util.exceptions.AuthenticationException;
import com.simplicite.util.exceptions.GetException;
import com.simplicite.util.tools.BusinessObjectTool;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Grant Hooks for Azure AD / Open ID Connect The call flow is 1. parseAuth => using the ID token,
 * we change the opaque login by the upn (User Principal Ladom), that is also the email 2.
 * preLoadGrant => we get the access token, then we call the Graph API and create or update the user
 * and its attributes 3. postLoadGrant => we do nothing for the moment
 *
 * <p>SessionInfo contains - getToken => access token - getIDToken => ID token - getRefreshToken =>
 * refresh token
 */
public class PlatformHooks extends PlatformHooksInterface {

    private static final String LADNEXT_MODULE = "ladnext_users";
    private static final String LADNEXT_HOME = "LadnextHome";
    private static final String ATT_USER_PRINCIPAL_LADNEXT = "userPrincipalName";
    private static final String ATT_USER_JOB_TITLE = "jobTitle";
    public static final String ATT_ROLE_MAPPER_TITRE = "titre";
    public static final String ATT_ROLE_MAPPER_DEPARTMENT = "department";
    public static final String ATT_ROLE_MAPPER_GROUPE = "groupe";

    /**
     * Call the Microsoft Graph API using the OIDC access token. Note that the lifetime of an access
     * token is short. If needed, get a new access token using the OIDC refresh token. This is
     * explained at
     * https://docs.microsoft.com/fr-fr/azure/active-directory/develop/v2-oauth2-auth-code-flow
     *
     * <p>See https://developer.microsoft.com/en-us/graph/graph-explorer for the format of the
     * queries e.g. sQuery = "https://graph.microsoft.com/v1.0/me" sQuery =
     * "https://graph.microsoft.com/v1.0/me/?$select=givenName,surname,jobTitle,department,officeLocation,city,postalCode";
     *
     * @param accessToken OIDC access token
     * @param sQuery Query for the Graph API
     * @return Returns a JSON object with the required attributes, returns null if an error occured
     */
    private JSONObject getMicrosoftGraphAPIAttributes(String accessToken, String sQuery) {
        // JSON returned by the Microsoft Graph API
        JSONObject graphObject = null;

        // call the Microsoft Graph API
        CloseableHttpClient httpClient = HttpClients.createDefault();

        try {
            HttpGet request = new HttpGet(sQuery);
            // add authorization request header (use the OIDC access token)
            request.setHeader("Authorization", "Bearer " + accessToken);
            request.setHeader("Content-Type", "application/json");

            // get response
            CloseableHttpResponse response = httpClient.execute(request);

            // The underlying HTTP connection is still held by the response object
            // to allow the response content to be streamed directly from the network socket.
            // In order to ensure correct deallocation of system resources
            // the user MUST call CloseableHttpResponse#close() from a finally clause.
            // Please note that if response content is not fully consumed the underlying
            // connection cannot be safely re-used and will be shut down and discarded
            // by the connection manager.

            if (200 == response.getStatusLine().getStatusCode()) {
                // HttpResponse Status is HTTP/1.1 200 OK
                try {
                    // get the response, assume its JSON and UTF8 encoded
                    HttpEntity entity = response.getEntity();
                    // use org.apache.http.util.EntityUtils to read json as string
                    String json = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                    graphObject = new JSONObject(json);
                    // ensure the stream fully consumed
                    EntityUtils.consume(entity);
                } finally {
                    response.close();
                }
            } else {
                throw new AuthenticationException(
                        "Unable to call Microsoft Graph API, status code is "
                                + response.getStatusLine().toString());
            }

            httpClient.close();

        } catch (Exception e) {
            AppLog.error("getGraphAPIAttributes - exception ", e, null);
        }

        return graphObject;
    }

    /**
     * Get the Azure AD attributes if available or set to "" if not available
     *
     * @param graphObject Microsoft Graph API JSON response
     * @param adField Graph API / Azure AD field
     */
    private String getADFieldValue(JSONObject graphObject, String adField) {
        if (graphObject.has(adField) && !graphObject.isNull(adField)) {
            // is it an array ?
            JSONArray jsonArray = graphObject.optJSONArray(adField);
            if (jsonArray != null) {
                // keep the first element
                if (!jsonArray.isNull(0)) {
                    return jsonArray.getString(0);
                } else {
                    return "";
                }
            } else {
                // most probable case
                return graphObject.getString(adField);
            }
        }
        return "";
    }

    /**
     * Given Ladnext role, assign the user to groups
     *
     * @param usr User DB object
     * @param role Ladnext role
     * @return Returns true if successful, returns false otherwise
     */
    private boolean setUserResponsibilities(ObjectDB usr, PlatformHooks.LadomRole role, Grant g)
            throws Exception {
        AppLog.info("Begin - setUserResponsibilities " + usr.getRowId() + " role " + role, null);

        Grant.removeAllResponsibilities(usr.getRowId());

        // use this Ladnext role to assign the group
        if (role != null && !Tool.isEmpty(role.getGroup())) {

            boolean respAssociated =
                    Grant.addResponsibility(
                            usr.getRowId(),
                            role.getGroup(),
                            Tool.getCurrentDate(-1),
                            "",
                            true,
                            LADNEXT_MODULE);
            if (!respAssociated) {
                throw new Exception("Responsibility not added");
            } else {
                AppLog.info("preLoadGrant : Added " + role.getGroup() + 
                " responsibility for user " + usr.getRowId(),
                        null);
            }
        }

        return true;
    }

    /**
     * Create a new Ladnext user, then assign Ladnext groups to the user according to the following
     * attributes : - the jobTitle - the department - the company or the city
     *
     * @param login This is the userPrincipalName a.k.a. "upn" in OIDC
     * @param graphObject Microsoft Graph API JSON response
     * @param role : Ladnext Role
     * @return Returns userId if success, null if failed
     */
    private String createUser(String login, JSONObject graphObject, PlatformHooks.LadomRole role, Grant g) {
        /*
        Singleton to use system objects with Local access
        Be careful to use it in thread safe methods	or only to read parameters, or to execute direct SQL queries/updates
        */

        AppLog.info("Begin createUser login " + login, null);
                
        Grant sys = Grant.getSystemAdmin();

        try {
            ObjectDB usr = sys.getTmpObject("LadomUser");
            synchronized (usr) { // thread-safe
                // initialize the user
                // ----------------------------------------------------------
                usr.resetValues(true);
                usr.setRowId(ObjectField.DEFAULT_ROW_ID);
                usr.setStatus(Grant.USER_ACTIVE); // set user as 'active'

                // Module of the user
                String ladnextModuleId = ModuleDB.getModuleId(LADNEXT_MODULE);
                usr.setFieldValue("row_module_id", ladnextModuleId);
                usr.setFieldValue("row_module_id.mdl_name", LADNEXT_MODULE);
                usr.setFieldValue("usr_home_id",View.getViewId(sys.getParameter("DEFAULT_USER_HOME", LADNEXT_HOME)));

                // Properties
                usr.setFieldValue("usr_login", login);
                usr.setFieldValue("usr_lang", Globals.LANG_FRENCH); // MUST BE to a Simplicité format
                //usr.setFieldValue("usr_country", "FR"); // MUST BE to a Simplicité format
                //usr.setFieldValue("usr_lang_pref", Globals.LANG_FRENCH);
                usr.setFieldValue("usr_image_id", "");

                // Contact
                usr.setFieldValue("usr_first_name", getADFieldValue(graphObject, "givenName"));
                usr.setFieldValue("usr_last_name", getADFieldValue(graphObject, "surname"));
                usr.setFieldValue("usr_email",getADFieldValue(graphObject, ATT_USER_PRINCIPAL_LADNEXT)); // "mail" is null but this is the upn
                                                              // ...
                usr.setFieldValue("usr_cell_num", getADFieldValue(graphObject, "mobilePhone"));
              //  usr.setFieldValue("usr_work_num", getADFieldValue(graphObject, "businessPhones"));

                // Address
                //usr.setFieldValue("usr_address1", getADFieldValue(graphObject, "streetAddress"));
                //usr.setFieldValue("usr_address2", getADFieldValue(graphObject, "officeLocation"));
                //usr.setFieldValue("usr_city", getADFieldValue(graphObject, "city"));
                //usr.setFieldValue("usr_zipcode", getADFieldValue(graphObject, "postalCode"));

                // Tite de l'agent
                usr.setFieldValue("ladUsrTitre", getADFieldValue(graphObject, ATT_USER_JOB_TITLE));
                usr.setFieldValue("ladUsrDepartement", getADFieldValue(graphObject, ATT_ROLE_MAPPER_DEPARTMENT));

                // create the user in DB and get a row id
                // ----------------------------------------------------------
                new BusinessObjectTool(usr).validateAndCreate();

                // DEBUG
                AppLog.info("createUser : Created user " + usr.getRowId(), null);

                // assign groups
                // ----------------------------------------------------------
                setUserResponsibilities(usr, role, g);
                
                AppLog.info("End createUser login " + login, null);
                        
            } // synchronized

            return usr.getRowId();

        } catch (Exception e) {
            AppLog.error("preLoadGrant: unable to create user ", e, null);
            return null;
        }
    }

    /**
     * Update a Ladnext user Each time a user log in, we need to update its rights according to the
     * Azure AD information
     *
     * @param login This is the OIDC userPrincipalName
     * @param graphObject Microsoft Graph API JSON response
     * @param role : Ladnext Role
     * @return Returns user id if successful, returns null otherwise
     */
    private String updateUser(String login, JSONObject graphObject, PlatformHooks.LadomRole role, Grant g) {
        /*
        Singleton to use system objects with Local access
        Be careful to use it in thread safe methods	or only to read parameters, or to execute direct SQL queries/updates
        */
        
        AppLog.info("Begin updateUser login " + login, null);
          
        Grant sys = Grant.getSystemAdmin();
        // get the user id
        //String uid = sys.simpleQuery("select row_id from m_user where usr_login = '" + login + "'");
        //AppLog.info("AzureAD - updateUser using - uid = " + uid, null);
        String uid = getUserIdIfExist(login);
        if (StringUtils.isEmpty(uid)){
            return null;
        }

        try {
            ObjectDB usr = sys.getTmpObject("LadomUser");
            //if (!usr.select(uid)) {
            //    return null;
            //}
            BusinessObjectTool bUserTools = new BusinessObjectTool(usr);
            try{
                bUserTools.getForUpdate(uid);
            }
            catch (GetException e){
                AppLog.error(getClass(), "GetException", e.getMessage(), null,
                        null);
            }

            synchronized (usr) { // thread-safe
                usr.setStatus(Grant.USER_ACTIVE); // set user as 'active'

                // Properties
                usr.setFieldValue("usr_lang", Globals.LANG_FRENCH); // MUST BE to a Simplicité format
                //usr.setFieldValue("usr_country", "FR"); // MUST BE to a Simplicité format
                //usr.setFieldValue("usr_lang_pref", Globals.LANG_FRENCH);
                usr.setFieldValue("usr_image_id", "");

                // Module of the user
                String ladnextModuleId = ModuleDB.getModuleId(LADNEXT_MODULE);
                usr.setFieldValue("row_module_id", ladnextModuleId);
                usr.setFieldValue("row_module_id.mdl_name", LADNEXT_MODULE);
                usr.setFieldValue("usr_home_id",
                        View.getViewId(sys.getParameter("DEFAULT_USER_HOME", LADNEXT_HOME)));

                // Contact
                usr.setFieldValue("usr_first_name", getADFieldValue(graphObject, "givenName"));
                usr.setFieldValue("usr_last_name", getADFieldValue(graphObject, "surname"));
                usr.setFieldValue("usr_email",
                        getADFieldValue(graphObject, ATT_USER_PRINCIPAL_LADNEXT)); // "mail" is null but this is the upn
                                                              // ...
                usr.setFieldValue("usr_cell_num", getADFieldValue(graphObject, "mobilePhone"));
                //usr.setFieldValue("usr_work_num", getADFieldValue(graphObject, "businessPhones"));

                // Address
                //usr.setFieldValue("usr_address1", getADFieldValue(graphObject, "streetAddress"));
                //usr.setFieldValue("usr_address2", getADFieldValue(graphObject, "officeLocation"));
                //usr.setFieldValue("usr_city", getADFieldValue(graphObject, "city"));
               // usr.setFieldValue("usr_zipcode", getADFieldValue(graphObject, "postalCode"));

                // Tite de l'agent
                usr.setFieldValue("ladUsrTitre", getADFieldValue(graphObject, ATT_USER_JOB_TITLE));
                usr.setFieldValue("ladUsrDepartement", getADFieldValue(graphObject, ATT_ROLE_MAPPER_DEPARTMENT));

                // update the user in DB
                // ----------------------------------------------------------
                bUserTools.validateAndUpdate();

                // assign groups
                // ----------------------------------------------------------
                setUserResponsibilities(usr, role, g);
                
                AppLog.info("End updateUser login " + login, null);
                 
            } // synchronized

            return usr.getRowId();

        } catch (Exception e) {
            AppLog.error("preLoadGrant: unable to update user " + uid, e, null);
            return null;
        }
    }

    private String getUserIdIfExist(String login) {
        String uid = "";
        try {
            Grant sys = Grant.getSystemAdmin();
            uid = sys.simpleQuery("select row_id from m_user where usr_login = '" + login + "'");
            AppLog.info("isUserExist using - uid = " + uid, null);
        }catch (Exception e) {
            AppLog.error(getClass(), "isUserExist",
                    "Erreur lors du test de l'existence de l'utilisateur " + login,
                    null, null);
            return uid;
        }
        return uid;
    }

    /**
     * This method is called for parsing authentication string to extract user login. The login is
     * updated using the upn field of the ID token.
     *
     * @param sys System admin grant
     * @param info Session info
     * @return Returns the new login if successful, returns info.getLogin() otherwise
     */
    @Override
    public String parseAuth(Grant sys, SessionInfo info) {
        AppLog.info("Begin - parseAuth " + sys.getAuthProvider(), null);
		AppLog.info("parseAuth SessionInfo:" + info , null);
		
        if ((null == info) || (null == info.getIDToken())) {
            // do nothing, if we use a local login, the ID token should be null
            // we could also use info.getProvider() to get the OIDC provider name
            return null == info ? "" : info.getLogin();
        }
        String login = info.getLogin(); // get login as set by the IdP (sub field by default)

        try {
            // get the ID token as JWT
            String idToken = info.getIDToken();
            // NB: you can decode idToken using htltps://jwt.ms/

            // if we use a local login, the ID token is null and we won't change the login
            if (!Tool.isEmpty(idToken)) {
                // get the decoded ID token as a JSON object
                AppLog.info("parseAuth - Decode ID token and get payLoad", null);
                java.util.Base64.Decoder decoder = java.util.Base64.getUrlDecoder();
                String[] parts =
                        idToken.split("\\."); // split out the "parts" (header, payload and signature)

                String payload = new String(decoder.decode(parts[1]));
                JSONObject payLoadJson = new JSONObject(payload);
                String upn = payLoadJson.optString("upn");

				AppLog.info("parseAuth - upn " + upn, null);
 
                if (upn != null && !upn.isEmpty()) {
                    login = upn;
                } else {
                    throw new Exception("Could not parse login from token");
                }
            }
        } catch (Exception e) {
            AppLog.error("parseAuth - exception", e, null);
            login = ""; // must return empty string, not null, to tell the auth is rejected
        }
        AppLog.info("End - parseAuth : Setting login OK ", null);

        return login;
    }

    /**
     * This method is called before loading grant
     *
     * @param g Grant (mostly empty when calling this function)
     */
    public void preLoadGrant(Grant g) {
        AppLog.info("Begin preLoadGrant g " + g.toString(), null);

		// Pas de règles specifiques
		if (Grant.isTechnicalUser(g.getLogin()))
			return;
		
        // the method 'preLoadGrant' can be called even if the user is not logged ? try to check
        // this case
        // check also the authentication method : we must have a valid ID token when using OIDC
        // the method 'preLoadGrant' can be called even if the user is not logged ? try to check
        // this case
        // check also the authentication method : we must have a valid ID token when using OIDC
        SessionInfo info = g.getSessionInfo();
        if ((null == info) || (null == info.getIDToken())) {
            AppLog.info("Failed to retrieve informations", null);
            return;
        }
        // Microsoft Graph API: user attributes we need on return
        // note that the possibilities are limited :
        // https://docs.microsoft.com/en-us/graph/query-parameters
        // to test a query, see also https://developer.microsoft.com/en-us/graph/graph-explorer
        String sQueryAttributes =
                "https://graph.microsoft.com/v1.0/me/?$select=userPrincipalName,givenName,surname,mail,mobilePhone,businessPhones,jobTitle,department,companyName,officeLocation,streetAddress,city,postalCode,country";

        // call the Microsoft Graph API using the access token
        JSONObject graphObject = getMicrosoftGraphAPIAttributes(info.getToken(), sQueryAttributes);

        AppLog.info("Graph object:" + graphObject, null);
        // only if OIDC authentication method is used and the access token was valid
        if (null != graphObject) {
            try {
                // Set the login as the email (instead of the default opaque ID given by Azure AD)
                String login = graphObject.getString(ATT_USER_PRINCIPAL_LADNEXT);
                if (Tool.isEmpty(login)) {
                    throw new AuthenticationException("Empty login");
                }
                // retrieve Ladnext role given AD information
                PlatformHooks.LadomRole role = getUserRoleByADinfo(graphObject);

                String userId = getUserIdIfExist(login);
                AppLog.info("preLoadGrant : userId user " + userId + " login " + login, null);

	            if (StringUtils.isEmpty(userId)){
                //if (!Grant.exists(login, false)) {
	                 // create the user in database
	                 AppLog.info("AzureAD - preLoadGrant : Creating user ", null);
	                 userId = createUser(login, graphObject, role, g);
	            } else {
	                 // update user attributes in database
	                 AppLog.info("AzureAD - preLoadGrant : Updating user ", null);
	                 userId = updateUser(login, graphObject, role, g);
	            }

                g.setLang(Globals.LANG_FRENCH);
                g.setLangPreference(Globals.LANG_FRENCH);

            } catch (Exception e) {
                AppLog.error("preLoadGrant - exception", e, null);
                throw new RuntimeException("Could'not login properly.", e);
            }
            AppLog.info("End preLoadGrant: " + g, null);
        }
    }

    /**
     * Given AD information, retrieve the Ladnext role that matches the AD Information of the user
     * or null if no match has been found
     *
     * @param graphObject Microsoft Graph API JSON response
     * @return returns a Ladnext role or null
     */
    public PlatformHooks.LadomRole getUserRoleByADinfo(JSONObject graphObject) {
        // get the jobTitle and the city
        String jobTitle = getADFieldValue(graphObject, ATT_USER_JOB_TITLE);
        String department = getADFieldValue(graphObject, ATT_ROLE_MAPPER_DEPARTMENT);
		
		AppLog.info("Begin getUserRoleByADinfo - jobTitle : " + jobTitle + " department " + department , null);
		     
        LadomRoleMapper.RoleInfo roleInfo =
                new LadomRoleMapper().getRoleInfo(LadomRoleMapper.JOB_TITLE, jobTitle);
        PlatformHooks.LadomRole ladomRole = new PlatformHooks.LadomRole();
        ladomRole.setGroup(roleInfo.getGroup());
        
        AppLog.info("End getUserRoleByADinfo: " + ladomRole.getGroup() , null);
        
        return ladomRole;
    }

    /** This method is called after loading grant */
    public void postLoadGrant(Grant g) {
        AppLog.info("AzureAD - postLoadGrant " + g.toString() , null );

		// Pas de règles specifiques
		if (Grant.isTechnicalUser(g.getLogin()))
			return;


        // the method 'postLoadGrant' can be called even if the user is not logged, try to check
        // this case
        // check also if the authentication method OAuth2
        SessionInfo info = g.getSessionInfo();

        AppLog.debug("AzureAD - postLoadGrant info " + info);
        if ((null == info) || !g.isOAuth2AuthMethod()) {
            AppLog.debug("AzureAD - postLoadGrant : not logged");
        }

    }

    /**
     * Given the list job title, retrieve the user group that matches them or null if no match has
     * been found
     *
     * @param jobTitles list of job titles
     * @return returns a user group
     */
    private Set<String> getUserGroupsByAgentTitles(List<String> jobTitles) {
        AppLog.info("PlatformHooks - getUserGroupsByAgentTitles : " + jobTitles, null);
        
        Set<String> userGroups = new HashSet<>();

        // get the role map based on jobTitle
        JSONArray roleMapper = Grant.getSystemAdmin().getJSONArrayParameter("LADOM_ROLE_MAPPER");
        if (roleMapper != null) {
            for (int i = 0; i < roleMapper.length(); ++i) {
                JSONObject role = roleMapper.getJSONObject(i);
                if (role.has(ATT_ROLE_MAPPER_TITRE)
                        && jobTitles.contains(role.getString(ATT_ROLE_MAPPER_TITRE))
                        && role.has(ATT_ROLE_MAPPER_GROUPE)) {
                    
                    AppLog.info("PlatformHooks - getUserGroupsByAgentTitles add group: " + role.getString(ATT_ROLE_MAPPER_GROUPE), null);
                    
                    userGroups.add(role.getString(ATT_ROLE_MAPPER_GROUPE));
                }
            }
        }
        return userGroups;
    }

    /** Classe décrivant un role enrichi pour Ladom */
    public class LadomRole {

        private String group;

        public String getGroup() {
            return group;
        }

        public void setGroup(String group) {
            this.group = group;
        }
    }
}

A priori c’est un problème de filtre ou de search-spec sur votre objet LadomUser.

  1. D’un côté vous faites un select en base / donc sans regle de gestion dans la couche logique :

Donc si ça dit “existe”, c’est qu’il existe bien physiquement (passez une requête à la main sur votre base en dehors de Simplicité pour vous en assurez/ via le DB access ou un autre client SQL).

(remarque : il faut toujours escaper les hosts values, ici le login qui vient de la page de login
uid = sys.simpleQuery("select row_id from m_user where usr_login = '" + Tool.toSQL(login) + "'");
sinon on pourrait taper comme login xxx' or '1'='1 et accéder à tous les login.
de plus vous avez réécrit la méthode static : User.getUserId(login); qui fait la même chose)

  1. Et de l’autre vous passez par un getForXXX de LadomUser qui doit avoir des règles de filtrages particuliers.
  • Il y a peut être une search-spec qui ne ramène rien alors que le user est bien en base, mais sans correspondre au critère de la search-spec qui ne le voit plus ?
  • Il faut que “designer” soit habilité à votre objet LadomUser, on peut lui donner des droits pas code et changer les propriétés de l’objet après instanciation / postLoad.
// Forcer tous les droits CRUD pour le système
sys.changeAccess("LadomUser", true, true, true, true);
// pas de filtres sur une instance particulière login_LadomUser
ObjectDB usr = sys.getObject("login_LadomUser", "LadomUser");
usr.resetFilters();
usr.setDefaultSearchSpec("1=1");

Dernier conseil : quand vous avez un pb lié à un accès aux données, activez temporairement les traces SQL dans les logs pour voir pourquoi un des “select” ne voit rien.

LOG_SQL_USER = yes + vider le cache.

Attention c’est très verbeux mais ça permet de comprendre quel “where” ne trouve pas votre User alors qu’il est en base (pb de search-spec ou données du User incomplètes).

Bonjour François,
J’ai remis le code initial c’est à dire avec les Grant.exists(login, false).
J’ai activé les logs user et system.
Je me connecte à un client sql externe à ma base local pour vérifier la présence ou nom de l’utilisateur dans la table m_user.

L’utilisateur roger@obsladom.onmicrosoft.com est absent au début du traitement.
Je débugge en pas à pas à coté. (Points d’arret dans la méthode parseAuth et dans le preLoadGrant.

Au début du traitement parseAuth et en sortant de cette méthode parseAuth (avant le return)
l’utilisateur est absent.
Au début de la méthode preLoadGrant l’utilisateur est crée.

L’utilisateur est crée entre le partAuth et le preLoadGrant mais je ne sais pas pourquoi ni par quelle méthode.

Voici un extrait des logs ou l’on voit l’insert de l’utilisateur :

2021-11-02 10:46:44,763|SIMPLICITE|DEBUG||http://4b2345910247:8080||DAUTHCS001|system|com.simplicite.webapp.servlets.OAuth2Servlet|callback||Authentication debug: OAuth2 callback servlet called for provider = [azuread]

2021-11-02 10:46:45,402|SIMPLICITE|INFO||http://4b2345910247:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|parseAuth||Event: Begin - parseAuth null
2021-11-02 10:46:45,403|SIMPLICITE|INFO||http://4b2345910247:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|parseAuth||Event: parseAuth - Decode ID token and get payLoad
2021-11-02 10:46:45,405|SIMPLICITE|INFO||http://4b2345910247:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|parseAuth||Event: End - parseAuth : Setting login OK

2021-11-02 10:46:45,445|SIMPLICITE|DEBUG||http://4b2345910247:8080||DCOREDB001|system|com.simplicite.util.engine.ObjectManager|query||SQL query: jdbc/simplicite: select row_id from m_user where usr_login=?
2021-11-02 10:46:45,446|SIMPLICITE|DEBUG||http://4b2345910247:8080||DCOREDB002|system|com.simplicite.util.engine.ObjectManager|query||Host: column usr_login value (roger@obsladom.onmicrosoft.com)
2021-11-02 10:46:45,447|SIMPLICITE|INFO||http://4b2345910247:8080||SQLSYSTEM|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select row_id from m_user where usr_login=? Hosts=[roger@obsladom.onmicrosoft.com]
2021-11-02 10:46:45,448|SIMPLICITE|DEBUG||http://4b2345910247:8080||DCOREDB001|system|com.simplicite.util.engine.ObjectManager|query||SQL query: jdbc/simplicite: select count(*) from m_module where row_id=31
2021-11-02 10:46:45,449|SIMPLICITE|INFO||http://4b2345910247:8080||SQLSYSTEM|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select count(*) from m_module where row_id=31 Hosts=

2021-11-02 10:46:45,459|SIMPLICITE|DEBUG||http://4b2345910247:8080||DCOREDB001|system|com.simplicite.util.engine.ObjectManager|update||SQL query: insert into m_rowid (row_id,rid_table,rid_curval) values (4,'m_user.row_id',14)


2021-11-02 10:46:45,893|SIMPLICITE|INFO||http://4b2345910247:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|preLoadGrant||Event: Graph object:{"country":null,"mail":null,"city":null,"givenName":"roger","jobTitle":"Agent Instucteur Act/Pme","companyName":"LADOM","postalCode":null,"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users(userPrincipalName,givenName,surname,mail,mobilePhone,businessPhones,jobTitle,department,companyName,officeLocation,streetAddress,city,postalCode,country)/$entity","businessPhones":[],"mobilePhone":null,"officeLocation":null,"streetAddress":null,"surname":"back","department":"La réunion","userPrincipalName":"roger@obsladom.onmicrosoft.com"}

Voyez vous l’insert en base dans m_user, avec quelles données ?
Avec les couches AD Azure + JWT, il y a peut être une création de User “minimal” avec les infos contenues dans le payload / UserInfos.

@david ça te dit quelque chose ? je n’ai pas tout l’historique de la mise en place des interfaces JWT.
A ma connaissance, la création automatique du User se fait si on se synchronise avec KeyCloak, on est peut être dans un cas hybride.

UPDATE : Voir si le paramètre SYNC_USER=true car il force la création du user.

On peut forcer la synchro en mettant "sync": true au niveau du provider dans AUTH_PROVIDER

Dans ce cas le user est créé ou mis à jour s’il existe dès l’appel de l’URL callback OAutH2/OpenIDConnect et l’appel du endpoint “userinfo”

NB: Le mapping éventuel entre les attributs du userinfo et les fields du user est géré via "userinfo_mappings" : {...} dans AUTH_PROVIDER

Le paramètre est bien valorisé à SYNC_USER=true, cela explique la création de l’utilisateur.
Nous avons un OAUTH2_USERINFO_MAPPINGS de renseigner à la place de userinfo_mappings dans
AUTH_PROVIDER mais cela ne semble pas appelé dans le bon timing.

Est ce qu’il y a un intérêt à faire une méthode createUser dans PlateformHook alors que par configuration
le code ne sera pas appelé du fait du callback ?

Je suis parti des échanges https://community.simplicite.io/t/probleme-dauthentification-azure-ad/2934/25.
mais je vois pas bien les interactions entre la conf et le code dans plateform.

Le param système OAUTH2_USERINFO_MAPPINGS <nom du provider> est une manière alternative (historique) pour renseigner l’attribut userinfo_mappings du provider dans AUTH_PROVIDER. C’est donc la même chose.

C’est vrai pour tous les attributs => pour un provider myprovider et pour un attribut xxx => on cherche d’abord xxx dans le bloc myprovider de AUTH_PROVIDER, puis à défaut, un éventuel param système OAUTH2_XXX myprovider.

Comme indiqué plus haut la synchro user est faite juste après l’appel du userinfo lors du rappel de l’URL de callback par l’IdP. Si c’est trop tôt pour vous, désactivez cette synchro paramétrable et gérez ça spécifiquement ça plus tard (les infos du userinfo restent disponibles dans le session info).

C’était trop tôt dans la mesure ou je ne connaissais pas ce mécanisme.
J’ai fait plusieurs modification mais j’ai toujours des problèmes.

Dans le createUser cela fonctionne par contre dans l’update User

Quand je fais

 ObjectDB ladomUser = sys.getTmpObject("LadomUser");
ou
 ObjectDB ladomUser = sys.getTmpObject("SimpleUser");

le ladomUser.select(uid) retourne false et le traitement s’arrete mais il n’est plus possible de faire de mise à jour ni de se connecter.

Donc j’ai changé par

ObjectDB ladomUser = sys.getTmpObject("User");

le ladomUser.select(uid) retourne true.

mais si le code suivant s’execute il ne fait rien et j’ai une boucle.

                // update the user in DB
                // ----------------------------------------------------------
                new BusinessObjectTool(ladomUser).validateAndUpdate();

                // assign groups
                // ----------------------------------------------------------
                setUserResponsibilities(ladomUser, role, g);

Remarque : LadomUser hérite de SimpleUser.

Est ce que vous voyez d’ou pourrait venir le problème de boucle et de non mise à jour des données?

C’est peut être lié. Le traitement de mise à jour des responsabilités supprime toutes responsabilités et lui fonctionne…

Est ce qu’il y a un cas d’usage pour passer le paramètre SYNC_USER = true ?

Comme déjà indiqué si un get/select ne ramène rien, vous pouvez regarder les logs SQL pour comprendre l’origine du where qui filtre / ou forcer le retrait des filtres sur votre instance :

Sur la boucle, vous avez peut être du code this.save ou this.update dans un preSave ou preUpdate qui boucle car travaille sur la même instance (votre tmp). Utilisez une instance particulière (dans mon exemple login_LadomUser) pour isoler ces parties de code et ne pas boucler dans les hooks de LadomUser :

if (!getInstanceName().equals("login_LadomUser")) ...

Sinon il faut préférer le validateAndSave pour passer par le preSave + preUpdate + postUpdate postSave.
validateAndUpdate ne fait pas le pre/postSave.

Bonjour,

J’ai conservé AUTH_PROVIDER avec SYNC_USER = true et OAUTH2_USERINFO_MAPPINGS pour renseigner l’attribut userinfo_mappings
C’est correct : l’utilisateur est crée via le callback mise à jour avec ses responsabilités via preLoadGrant de la classe laPlatformHooks.
Il devait y avoir un problème de droits car c’est mieux en mettant le code de François

// Forcer tous les droits CRUD pour le système
sys.changeAccess("LadomUser", true, true, true, true);
// pas de filtres sur une instance particulière login_LadomUser
ObjectDB usr = sys.getObject("login_LadomUser", "LadomUser");
usr.resetFilters();
usr.setDefaultSearchSpec("1=1");

Par contre j’ai toujours la boucle. J’ai remplacé le `validateAndUpdate par un validateAndSave et ajouté if (!getInstanceName().equals(“login_LadomUser”)) { …} dans le postLoad de LadomUser. Il n’y a pas de code sur des preSave ou preUpdate.
Entre la fin preLoadGrant||Event: End preLoadGrant et le cycle suivant PlatformHooks|preLoadGrant||Event: Begin preLoadGrant

il n’y a que des traces:
SQLUSER|system|DBAccess|SQL|query
REPOSITORY|system|ObjectIndex|search
SQLUSER|system|DBAccess|SQL|query|SQL=select
REPOSITORY|roger@obsladom.onmicrosoft.com|UserSysParam|search||Message=found 1
REPOSITORY|system|ModuleLink|search||Message=found 14
REPOSITORY|roger@obsladom.onmicrosoft.com|UserSysParam|update|38|Message=
REPOSITORY|roger@obsladom.onmicrosoft.com|User|search||Message=found 1
SQLUSER|system|DBAccess|SQL|query|SQL=delete from m_object_usage

2021-11-03 15:48:10,591|SIMPLICITE|INFO||http://f3ea7a541463:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|preLoadGrant||Event: End preLoadGrant: {"endpoint":1,"responsibilities":[],"sessionid":"2C8E99EE8BC94ADAAF0A0B4036540B66","login":"roger@obsladom.onmicrosoft.com","lang":"FRA","userid":0}
2021-11-03 15:48:10,593|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.idx_key, t.idx_object, t.idx_row_id, t.idx_ukey, t.idx_all from m_index t where (t.idx_key like ?) order by t.idx_key asc Hosts=[Responsability:76]
2021-11-03 15:48:10,595|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|system|ObjectIndex|search||Message=found 0 row(s) SQL=select t.idx_key, t.idx_object, t.idx_row_id, t.idx_ukey, t.idx_all from m_index t where (t.idx_key like ?) order by t.idx_key asc Hosts=[Responsability:76]
2021-11-03 15:48:10,596|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select p.usp_value from m_system s, m_user_sysparam p, m_user u where s.row_id = p.usp_param_id and p.usp_user_id = u.row_id and s.sys_code = 'DISPOSITION' and u.usr_login = 'roger@obsladom.onmicrosoft.com' Hosts=
2021-11-03 15:48:10,602|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: insert into m_index (idx_key,idx_object,idx_row_id,idx_ukey,idx_all) values (?,?,?,?,null) Hosts=[Responsability:76][Responsability][76][11/02/2021]
2021-11-03 15:48:10,603|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|system|ObjectIndex|create|Responsability:76|Message= SQL=insert into m_index (idx_key,idx_object,idx_row_id,idx_ukey,idx_all) values (?,?,?,?,null) Hosts=[Responsability:76][Responsability][76][11/02/2021]
2021-11-03 15:48:10,609|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select row_id from m_disposition where dis_code = 'default' Hosts=
2021-11-03 15:48:10,612|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select r.res_object, r.res_code from m_resource r where r.res_object = 'Disposition:6' Hosts=
2021-11-03 15:48:10,615|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select r.res_object, r.res_code from m_resource r where r.res_object not like 'Disposition:%' or r.res_object = 'Disposition:6' Hosts=
2021-11-03 15:48:10,622|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select row_id from m_user where usr_login = 'roger@obsladom.onmicrosoft.com' Hosts=
2021-11-03 15:48:10,728|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.usp_user_id, t_usp_user_id.usr_login, t.usp_param_id, t_usp_param_id.sys_code, t.usp_value, t_usp_param_id.sys_type, t_usp_param_id.sys_value, t_usp_param_id.sys_desc, t.row_module_id, t_row_module_id.mdl_name, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user_sysparam t left outer join m_user t_usp_user_id on (t.usp_user_id=t_usp_user_id.row_id) left outer join m_system t_usp_param_id on (t.usp_param_id=t_usp_param_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) where (t.usp_user_id=?) and (t.usp_param_id=?) order by t_usp_user_id.usr_login asc, t_usp_param_id.sys_code asc, t.row_id asc Hosts=[13][50]
2021-11-03 15:48:10,730|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|roger@obsladom.onmicrosoft.com|UserSysParam|search||Message=found 0 row(s) SQL=select t.row_id, t.usp_user_id, t_usp_user_id.usr_login, t.usp_param_id, t_usp_param_id.sys_code, t.usp_value, t_usp_param_id.sys_type, t_usp_param_id.sys_value, t_usp_param_id.sys_desc, t.row_module_id, t_row_module_id.mdl_name, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user_sysparam t left outer join m_user t_usp_user_id on (t.usp_user_id=t_usp_user_id.row_id) left outer join m_system t_usp_param_id on (t.usp_param_id=t_usp_param_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) where (t.usp_user_id=?) and (t.usp_param_id=?) order by t_usp_user_id.usr_login asc, t_usp_param_id.sys_code asc, t.row_id asc Hosts=[13][50]
2021-11-03 15:48:10,732|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select t.row_id, t.trv_name, t.trv_autosearch, x.tsl_value from m_treeview t left outer join m_translate x on (x.tsl_id=t.row_id and x.tsl_type='W' and (x.tsl_lang='ENU' or x.tsl_lang='ANY')) order by t.trv_name Hosts=
2021-11-03 15:48:10,736|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select o.row_id, o.trv_level, o.trv_parent_id, a.obj_name, f.fld_name, o.trv_external_id, o.trv_action_id, o.trv_shortcut_id, p.pcs_name, o.trv_subtree_id, o.trv_open, o.trv_pagine, o.trv_onclick, t.trv_name, t.trv_autosearch, x.tsl_value, e.obj_searchspec, e.obj_name, y.tsl_value, s.shc_url, s.shc_name, o.trv_action, o.trv_nolist from m_treeviewobj o left outer join m_object a on (a.row_id = o.trv_object_id) left outer join m_field f on (f.row_id = o.trv_field_id) left outer join m_treeview t on (t.row_id = o.trv_subtree_id) left outer join bpm_process p on (p.row_id = o.trv_process_id) left outer join m_object e on (e.row_id = o.trv_external_id) left outer join m_translate x on (x.tsl_id=e.row_id and x.tsl_type='O' and (x.tsl_lang='ENU' or x.tsl_lang='ANY')) left outer join m_shortcut s on (s.row_id = o.trv_shortcut_id) left outer join m_translate y on (y.tsl_id=e.row_id and y.tsl_type='S' and (y.tsl_lang='ENU' or y.tsl_lang='ANY')) where o.trv_tree_id=1 order by o.trv_level Hosts=
2021-11-03 15:48:10,740|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select o.row_id, o.trv_level, o.trv_parent_id, a.obj_name, f.fld_name, o.trv_external_id, o.trv_action_id, o.trv_shortcut_id, p.pcs_name, o.trv_subtree_id, o.trv_open, o.trv_pagine, o.trv_onclick, t.trv_name, t.trv_autosearch, x.tsl_value, e.obj_searchspec, e.obj_name, y.tsl_value, s.shc_url, s.shc_name, o.trv_action, o.trv_nolist from m_treeviewobj o left outer join m_object a on (a.row_id = o.trv_object_id) left outer join m_field f on (f.row_id = o.trv_field_id) left outer join m_treeview t on (t.row_id = o.trv_subtree_id) left outer join bpm_process p on (p.row_id = o.trv_process_id) left outer join m_object e on (e.row_id = o.trv_external_id) left outer join m_translate x on (x.tsl_id=e.row_id and x.tsl_type='O' and (x.tsl_lang='ENU' or x.tsl_lang='ANY')) left outer join m_shortcut s on (s.row_id = o.trv_shortcut_id) left outer join m_translate y on (y.tsl_id=e.row_id and y.tsl_type='S' and (y.tsl_lang='ENU' or y.tsl_lang='ANY')) where o.trv_tree_id=3 order by o.trv_level Hosts=
2021-11-03 15:48:10,743|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select o.row_id, o.trv_level, o.trv_parent_id, a.obj_name, f.fld_name, o.trv_external_id, o.trv_action_id, o.trv_shortcut_id, p.pcs_name, o.trv_subtree_id, o.trv_open, o.trv_pagine, o.trv_onclick, t.trv_name, t.trv_autosearch, x.tsl_value, e.obj_searchspec, e.obj_name, y.tsl_value, s.shc_url, s.shc_name, o.trv_action, o.trv_nolist from m_treeviewobj o left outer join m_object a on (a.row_id = o.trv_object_id) left outer join m_field f on (f.row_id = o.trv_field_id) left outer join m_treeview t on (t.row_id = o.trv_subtree_id) left outer join bpm_process p on (p.row_id = o.trv_process_id) left outer join m_object e on (e.row_id = o.trv_external_id) left outer join m_translate x on (x.tsl_id=e.row_id and x.tsl_type='O' and (x.tsl_lang='ENU' or x.tsl_lang='ANY')) left outer join m_shortcut s on (s.row_id = o.trv_shortcut_id) left outer join m_translate y on (y.tsl_id=e.row_id and y.tsl_type='S' and (y.tsl_lang='ENU' or y.tsl_lang='ANY')) where o.trv_tree_id=2 order by o.trv_level Hosts=
2021-11-03 15:48:10,747|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select r.row_id,l.tsl_value,r.rch_request,r.rch_public,o.obj_name from m_object o inner join m_research r on (r.rch_object_id=o.row_id and (r.rch_user_id=13 or r.rch_public='1')) left outer join m_translate l on (l.tsl_id=r.row_id and l.tsl_type='Q' and (l.tsl_lang='ENU' or l.tsl_lang='ANY')) order by o.obj_name asc, l.tsl_value asc Hosts=
2021-11-03 15:48:10,757|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select row_id from m_user where usr_login = 'roger@obsladom.onmicrosoft.com' Hosts=
2021-11-03 15:48:10,760|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select row_id from m_system where sys_code = 'SCOPE_PREFS' Hosts=
2021-11-03 15:48:10,763|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.usp_user_id, t_usp_user_id.usr_login, t.usp_param_id, t_usp_param_id.sys_code, t.usp_value, t_usp_param_id.sys_type, t_usp_param_id.sys_value, t_usp_param_id.sys_desc, t.row_module_id, t_row_module_id.mdl_name, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user_sysparam t left outer join m_user t_usp_user_id on (t.usp_user_id=t_usp_user_id.row_id) left outer join m_system t_usp_param_id on (t.usp_param_id=t_usp_param_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) where (t.usp_user_id=?) and (t.usp_param_id=?) order by t_usp_user_id.usr_login asc, t_usp_param_id.sys_code asc, t.row_id asc Hosts=[13][449]
2021-11-03 15:48:10,764|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|roger@obsladom.onmicrosoft.com|UserSysParam|search||Message=found 1 row(s) SQL=select t.row_id, t.usp_user_id, t_usp_user_id.usr_login, t.usp_param_id, t_usp_param_id.sys_code, t.usp_value, t_usp_param_id.sys_type, t_usp_param_id.sys_value, t_usp_param_id.sys_desc, t.row_module_id, t_row_module_id.mdl_name, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user_sysparam t left outer join m_user t_usp_user_id on (t.usp_user_id=t_usp_user_id.row_id) left outer join m_system t_usp_param_id on (t.usp_param_id=t_usp_param_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) where (t.usp_user_id=?) and (t.usp_param_id=?) order by t_usp_user_id.usr_login asc, t_usp_param_id.sys_code asc, t.row_id asc Hosts=[13][449]
2021-11-03 15:48:10,766|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select mdl_name from m_module where row_id = 40 Hosts=
2021-11-03 15:48:10,768|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select mdl_name from m_module where row_id = 40 Hosts=
2021-11-03 15:48:10,773|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select m.mdl_name from m_module m, m_user t where m.row_id=t.row_module_id and t.row_id=13 Hosts=
2021-11-03 15:48:10,779|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select m.mdl_name from m_module m, m_system t where m.row_id=t.row_module_id and t.row_id=449 Hosts=
2021-11-03 15:48:10,789|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.mdk_parent_id, t_mdk_parent_id.mdl_name, t.row_module_id, t_row_module_id.mdl_name, t.mdk_cascad, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_module_link t left outer join m_module t_mdk_parent_id on (t.mdk_parent_id=t_mdk_parent_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id)  order by t.row_id asc Hosts=
2021-11-03 15:48:10,791|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|system|ModuleLink|search||Message=found 14 row(s) SQL=select t.row_id, t.mdk_parent_id, t_mdk_parent_id.mdl_name, t.row_module_id, t_row_module_id.mdl_name, t.mdk_cascad, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_module_link t left outer join m_module t_mdk_parent_id on (t.mdk_parent_id=t_mdk_parent_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id)  order by t.row_id asc Hosts=
2021-11-03 15:48:10,804|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: update m_user_sysparam set updated_dt=?,updated_by=? where row_id=? Hosts=[2021-11-03 15:48:10][roger@obsladom.onmicrosoft.com][38]
2021-11-03 15:48:10,804|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|roger@obsladom.onmicrosoft.com|UserSysParam|update|38|Message= SQL=update m_user_sysparam set updated_dt=?,updated_by=? where row_id=? Hosts=[2021-11-03 15:48:10][roger@obsladom.onmicrosoft.com][38]
2021-11-03 15:48:10,810|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=select row_id from m_user where usr_login = 'roger@obsladom.onmicrosoft.com' Hosts=
2021-11-03 15:48:10,847|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=jdbc/simplicite: select t.row_id, t.usr_image_id, t.usr_login, t.usr_timezone, t.usr_minrows, t.usr_maxrows, t.usr_title, t.usr_first_name, t.usr_last_name, t.usr_lang, t.usr_email, t.usr_work_num, t.usr_home_num, t.usr_cell_num, t.usr_active, t.usr_home_id, t_usr_home_id.viw_name, t.usr_address1, t.usr_address2, t.usr_zipcode, t.usr_city, t.usr_state, t.usr_country, t.row_module_id, t_row_module_id.mdl_name, t.usr_menu, t.usr_menu_defcollapsed, t.usr_menu_defdomain_id, t_usr_menu_defdomain_id.obj_name, t.usr_logout, t.usr_last_logon, t.usr_dateformat, t.usr_lang_pref, t.usr_uuid, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user t left outer join m_view t_usr_home_id on (t.usr_home_id=t_usr_home_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) left outer join m_object t_usr_menu_defdomain_id on (t.usr_menu_defdomain_id=t_usr_menu_defdomain_id.row_id) where (t.row_id=?) and (t.usr_login is not null and t.usr_login not in ('system','public')) order by t.usr_login asc, t.row_id asc Hosts=[13]
2021-11-03 15:48:10,849|SIMPLICITE|INFO||http://f3ea7a541463:8080||REPOSITORY|roger@obsladom.onmicrosoft.com|User|search||Message=found 1 row(s) SQL=select t.row_id, t.usr_image_id, t.usr_login, t.usr_timezone, t.usr_minrows, t.usr_maxrows, t.usr_title, t.usr_first_name, t.usr_last_name, t.usr_lang, t.usr_email, t.usr_work_num, t.usr_home_num, t.usr_cell_num, t.usr_active, t.usr_home_id, t_usr_home_id.viw_name, t.usr_address1, t.usr_address2, t.usr_zipcode, t.usr_city, t.usr_state, t.usr_country, t.row_module_id, t_row_module_id.mdl_name, t.usr_menu, t.usr_menu_defcollapsed, t.usr_menu_defdomain_id, t_usr_menu_defdomain_id.obj_name, t.usr_logout, t.usr_last_logon, t.usr_dateformat, t.usr_lang_pref, t.usr_uuid, t.created_dt, t.created_by, t.updated_dt, t.updated_by from m_user t left outer join m_view t_usr_home_id on (t.usr_home_id=t_usr_home_id.row_id) left outer join m_module t_row_module_id on (t.row_module_id=t_row_module_id.row_id) left outer join m_object t_usr_menu_defdomain_id on (t.usr_menu_defdomain_id=t_usr_menu_defdomain_id.row_id) where (t.row_id=?) and (t.usr_login is not null and t.usr_login not in ('system','public')) order by t.usr_login asc, t.row_id asc Variables=[13]
2021-11-03 15:48:10,851|SIMPLICITE|INFO||http://f3ea7a541463:8080||SQLUSER|system|DBAccess|SQL|query|SQL=delete from m_object_usage where obu_user_id=13 and obu_session='2C8E99EE8BC94ADAAF0A0B4036540B66' Hosts=
2021-11-03 15:48:10,853|SIMPLICITE|INFO||http://f3ea7a541463:8080||INFO|system|com.simplicite.commons.ladnext.PlatformHooks|preLoadGrant||Event: Begin preLoadGrant

Il y a un traitement qui recharge les droits au logon (avant postLoadGrant), ça pourrait expliquer cette boucle :

Si le scope (la page d’accueil affectée au User) n’est pas renseignée ou qu’elle ne matche pas avec une page d’accueil de ses droits, Simplicité réaffecte automatiquement un scope valide (celle demandée par URL ?_scope=xxx ou la première autorisée) et recharge les droits pour ce scope valide.

  • Avez vous affecté une page d’accueil au User (usr_home_id = row_id de la View) dans votre création/mise à jour du User au preLoadGrant ?
  • Si oui fait elle bien partie de ses groupes autorisés ?

Nickel, merci François c’est bien ça!

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.