-
Type: Bug
-
Status: Resolved
-
Priority: Minor
-
Resolution: Fixed
-
Affects Version/s: None
-
Fix Version/s: 10.10-HF36, 11.4, 2021.0
-
Component/s: Authentication, SAML
-
Tags:
-
Sprint:nxFG 11.3.1
Context
In the context of a SAML Authentication, we can create/update the User and the associated profile during the login.
This is typically achieved via AbstractUserMapper.getOrCreateAndUpdateNuxeoPrincipal, if the mapping class or script provides profile information, we will try to create it:
if (userModel != null && profileAttributes.size() > 0 && update) { ... new UnrestrictedSessionRunner(repoName) { @Override public void run() { DocumentModel profile = UPS.getUserProfileDocument(login, session); updateProfile(session, profileAttributes, profile); } }.runUnrestricted(); ... }
The problem is that depending on what URL is used as a callback, the transaction may not have been started by the RequestControllerFilter and as a consequence try to use the CoreSession will raise an error
Cannot create a CoreSession outside a transaction
Error
2020-11-05T23:13:45,841 ERROR [http-nio-0.0.0.0-8080-exec-10] [org.nuxeo.ecm.platform.web.common.exceptionhandling.DefaultNuxeoExceptionHandler] org.nuxeo.ecm.core.api.NuxeoException: Cannot create a CoreSession outside a transac tion at org.nuxeo.ecm.core.api.local.LocalSession.<init>(LocalSession.java:66) at org.nuxeo.ecm.core.api.CoreSessionServiceImpl.createCoreSession(CoreSessionServiceImpl.java:35) at org.nuxeo.ecm.core.api.CoreInstance.getCoreSession(CoreInstance.java:100) at org.nuxeo.ecm.core.api.CoreInstance.getCoreSession(CoreInstance.java:49) at org.nuxeo.ecm.core.api.UnrestrictedSessionRunner.runUnrestricted(UnrestrictedSessionRunner.java:122) at org.nuxeo.usermapper.extension.AbstractUserMapper.getOrCreateAndUpdateNuxeoPrincipal(AbstractUserMapper.java:122) at org.nuxeo.usermapper.service.UserMapperComponent.getOrCreateAndUpdateNuxeoPrincipal(UserMapperComponent.java:110) at org.nuxeo.ecm.platform.auth.saml.user.UserMapperBasedResolver.findOrCreateNuxeoUser(UserMapperBasedResolver.java:67) at org.nuxeo.ecm.platform.auth.saml.SAMLAuthenticationProvider.lambda$handleRetrieveIdentity$0(SAMLAuthenticationProvider.java:458) at org.nuxeo.runtime.api.Framework.loginAndDo(Framework.java:285) at org.nuxeo.runtime.api.Framework.doPrivileged(Framework.java:272) at org.nuxeo.ecm.platform.auth.saml.SAMLAuthenticationProvider.handleRetrieveIdentity(SAMLAuthenticationProvider.java:458) at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.handleRetrieveIdentity(NuxeoAuthenticationFilter.java:1012) at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilterInternal(NuxeoAuthenticationFilter.java:441) at org.nuxeo.ecm.platform.ui.web.auth.NuxeoAuthenticationFilter.doFilter(NuxeoAuthenticationFilter.java:336) ...
Solution
Update the code in AbstractUserMapper to hand the transaction.
We could use this has an opportunity to remove the usage of UnrestrictedSessionRunner and use something like:
TransactionHelper.runInTransaction(() -> { CoreInstance.doPrivileged(session, (CoreSession unrestrictedSession) -> { updateProfile(unrestrictedSession); }); });
- Is referenced in