Добавление ролей

Теперь добавим scopes в токен. Даже просто добавление списка ролей оказалось той еще задачей. Во многих инструкциях будет сказано, что настройка маппера в Keycloak Admin Console -> ваш realm → Clients → ваш клиент -> Вкладка Mappers. Но это не так. Пример настройки для получения ролей: 

 

 Перейди в Client Scopes: Твой realm → Clients → выбери своего клиента → вкладка Client scopes → кликни на дедикейтед скоп *-dedicated (например, my-client-dedicated). 

 Открой вкладку Mappers. 

 Нажми Configure a new mapper и выбери By configuration. 

 Выбери тип маппера: В выпадающем списке выбери User Realm Role. 

     Вот это ключевой момент: использование предустановленного типа, а не создание своего, гарантирует корректную внутреннюю структуру. 

 Проверь настройки (они должны заполниться автоматически): 

     Name: Оставь realm roles (или любое другое). 

     Token Claim Name: Убедись, что здесь realm_access . Это единственное правильное имя поля. 

     Add to userinfo: Убедись, что переключатель установлен в ON. 

     Add to access token / Add to ID token: Можно оставить OFF, если роли не нужны в самих JWT токенах. 

 Сохрани маппер (кнопка Save). 

 

   

 async def get_current_user_roles(request: Request) -> Optional[dict]:

 """Извлечение ролей"""

 access_token = request.cookies.get("access_token")

 if not access_token:

 return []

 try:

 claims = jwt.get_unverified_claims(access_token)

 roles = claims.get("realm_access", {}).get("roles", [])

 return roles

 except Exception:

 return []

...

@app.get("/", response_class=HTMLResponse)

async def simpleauth(request: Request):

 user = await get_current_user_from_cookie(request)

 if not user:

 login_url = get_login_url()

 html_content = f'<!DOCTYPE html><html><body><a href="{login_url}"><button>Авторизация</button></a></body></html>'

 else:

 roles = await get_current_user_roles(request)

 html_content = f'''<!DOCTYPE html><html><body><a href="/logout"><button>Выход</button></a>

 <p>Доступные ключи: {user.keys()}</p>

 <p>Доступные роли: {roles}</p>

 </body></html>'''

 return HTMLResponse(content=html_content, status_code=200)

 

   

  