GitHub user dosubot[bot] added a comment to the discussion: How to customize 
authentication in version 6

<!-- Answer -->
This is fascinating debugging! I think I can explain what's happening:

**Why `g.user` is a boolean**: [Superset's built-in `request_loader` returns 
`None` by 
default](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/security/manager.py#L398-L404)
 (only handling guest tokens when EMBEDDED_SUPERSET is enabled). When you 
override it, you're correctly returning a User object, but there's likely a 
code path where something else is setting `g.user` to a boolean. The error 
happens when `SupersetAuthView.login()` tries to check 
`g.user.is_authenticated` and `g.user` is `True` instead of a User object.

**Why `add_user()` doesn't persist immediately**: [add_user() does NOT 
automatically 
commit](https://github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/tests/integration_tests/base_tests.py#L133-L142).
 Without a commit, the user exists only in the SQLAlchemy session's pending 
state. Other queries (like `find_user()`) won't see it until committed.

**Why accessing `g.user.is_authenticated` fixes it**: This is the key insight - 
when you access `g.user`, it forces Flask-Login to re-evaluate and properly 
load the user. Without that access, the user object isn't fully materialized.

**Why multiple request_loader calls**: Each HTTP subrequest (CSS, JS, images, 
API calls for the React UI) triggers a new request context, each calling your 
`request_loader`. That's expected.

**Try this fix**:

```python
from superset.extensions import db

class CustomSecurityManager(SupersetSecurityManager):
    def request_loader(self, request):
        username = request.environ.get("REMOTE_USER")
        if not username:
            return None  # Must return None, not False
        
        user = self.find_user(username=username)
        
        if not user:
            log.info(f"Adding new user: {username}")
            user = self.add_user(
                username=username,
                first_name=request.environ.get("FIRST_NAME") or "",
                last_name=request.environ.get("LAST_NAME") or "",
                email=username,
                role=self.find_role("Gamma")
            )
            db.session.commit()  # Explicit commit is required!
            
            # Re-fetch to get a clean, attached user object
            user = self.find_user(username=username)
        
        return user  # Always return User object or None
```

The key changes:
1. **Explicit `db.session.commit()`** after `add_user()`
2. **Re-fetch the user** after creating to ensure you have a properly attached 
SQLAlchemy object
3. **Always return a User object or `None`** - never a boolean

The re-fetch after commit should eliminate the race condition you're 
experiencing and ensure the user object has all the proper attributes loaded.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot).*

---
<sup>How did I do? 
[Good](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=great_response)
 | 
[Irrelevant](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=irrelevant_answer)
 | 
[Incorrect](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=incorrect_sources)
 | 
[Verbose](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=too_verbose)
 | 
[Hallucination](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=hallucination)
 | [Report 
🐛](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=bug_report)
 | 
[Other](https://app.dosu.dev/response-feedback/6a5cc0cf-17bd-4685-946e-e806d3fd718c?feedback_type=other)</sup>

[![Chat with 
Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github)&nbsp;[![Open
 in 
Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=This%20is%20fascinating%20debugging%21%20I%20think%20I%20can%20explain%20what%27s%20happening%3A%0A%0A%2A%2AWhy%20%60g.user%60%20is%20a%20boolean%2A%2A%3A%20%5BSuperset%27s%20built-in%20%60request_loader%60%20returns%20%60None%60%20by%20default%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/superset/security/manager.py%23L398-L404%29%20%28only%20handling%20guest%20tokens%20when%20EMBEDDED_SUPERSET%20is%20enabled%29.%20When%20you%20override%20it%2C%20you%27re%20correctly%20returning%20a%20User%20object%2C%20but%20there%27s%20likely%20a%20code%20path%20where%20something%20else%20is%20setting%20%60g.user%60%20to%20a%20boolean.%20The%20error%20happens%20when%20%60SupersetAuthView.login%28%29%60%20tries%20to%20check
 
%20%60g.user.is_authenticated%60%20and%20%60g.user%60%20is%20%60True%60%20instead%20of%20a%20User%20object.%0A%0A%2A%2AWhy%20%60add_user%28%29%60%20doesn%27t%20persist%20immediately%2A%2A%3A%20%5Badd_user%28%29%20does%20NOT%20automatically%20commit%5D%28https%3A//github.com/apache/superset/blob/829e4d92d91ceae4b43b1ed3b063ffe45377799c/tests/integration_tests/base_tests.py%23L133-L142%29.%20Without%20a%20commit%2C%20the%20user%20exists%20only%20in%20the%20SQLAlchemy%20session%27s%20pending%20state.%20Other%20queries%20%28like%20%60find_user%28%29%60%29%20won%27t%20see%20it%20until%20committed.%0A%0A%2A%2AWhy%20accessing%20%60g.user.is_authenticated%60%20fixes%20it%2A%2A%3A%20This%20is%20the%20key%20insight%20-%20when%20you%20access%20%60g.user%60%2C%20it%20forces%20Flask-Login%20to%20re-evaluate%20and%20properly%20load%20the%20user.%20Without%20that%20access%2C%20the%20user%20object%20isn%27t%20fully%20materialized.%0A%0A%2A%2AWhy%20multiple%20request_loader%20calls%2A%2A%3A%20Each%2
 
0HTTP%20subrequest%20%28CSS%2C%20JS%2C%20images%2C%20API%20calls%20for%20the%20React%20UI%29%20triggers%20a%20new%20request%20context%2C%20each%20calling%20your%20%60request_loader%60.%20That%27s%20expected.%0A%0A%2A%2ATry%20this%20fix%2A%2A%3A%0A%0A%60%60%60python%0Afrom%20superset.extensions%20import%20db%0A%0Aclass%20CustomSecurityManager%28SupersetSecurityManager%29%3A%0A%20%20%20%20def%20request_loader%28self%2C%20request%29%3A%0A%20%20%20%20%20%20%20%20username%20%3D%20request.environ.get%28%22REMOTE_USER%22%29%0A%20%20%20%20%20%20%20%20if%20not%20username%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20None%20%20%23%20Must%20return%20None%2C%20not%20False%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20user%20%3D%20self.find_user%28username%3Dusername%29%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20if%20not%20user%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20log.info%28f%22Adding%20new%20user%3A%20%7Busername%7D%22%29%0A%20%20%20%20%20%20%20%20%20%20%20%20user%20%3
 
D%20self.add_user%28%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20username%3Dusername%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20first_name%3Drequest.environ.get%28%22FIRST_NAME%22%29%20or%20%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20last_name%3Drequest.environ.get%28%22LAST_NAME%22%29%20or%20%22%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20email%3Dusername%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20role%3Dself.find_role%28%22Gamma%22%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%29%0A%20%20%20%20%20%20%20%20%20%20%20%20db.session.commit%28%29%20%20%23%20Explicit%20commit%20is%20required%21%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Re-fetch%20to%20get%20a%20clean%2C%20attached%20user%20object%0A%20%20%20%20%20%20%20%20%20%20%20%20user%20%3D%20self.find_user%28username%3Dusername%29%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20return%20user%20%20%23%20Always%20return%20User%20object%20or
 
%20None%0A%60%60%60%0A%0AThe%20key%20changes%3A%0A1.%20%2A%2AExplicit%20%60db.session.commit%28%29%60%2A%2A%20after%20%60add_user%28%29%60%0A2.%20%2A%2ARe-fetch%20the%20user%2A%2A%20after%20creating%20to%20ensure%20you%20have%20a%20properly%20attached%20SQLAlchemy%20object%0A3.%20%2A%2AAlways%20return%20a%20User%20object%20or%20%60None%60%2A%2A%20-%20never%20a%20boolean%0A%0AThe%20re-fetch%20after%20commit%20should%20eliminate%20the%20race%20condition%20you%27re%20experiencing%20and%20ensure%20the%20user%20object%20has%20all%20the%20proper%20attributes%20loaded.)&nbsp;[![Join
 
Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share
 on 
X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/38199)

GitHub link: 
https://github.com/apache/superset/discussions/38199#discussioncomment-15904760

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: 
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to