You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Keycloak设计多服务SSO及多餐厅多角色用户访问系统的最佳实践咨询

Great question—this multi-tenant, role-per-context scenario is super common in SaaS apps like restaurant management tools, and Keycloak absolutely has the tools to pull this off cleanly if you structure it right. Let’s break down the best practice that’s easy to build and maintain, tailored exactly to your restaurant use case.

Core Approach: Map Restaurants to Groups, Roles to Permissions

Here’s the thing about Keycloak: it’s powerful, but all those options (scopes, policies, groups) can feel overwhelming at first. The key is to map your real-world entities directly to Keycloak’s features without overcomplicating it:

  • Restaurants = Keycloak Groups: Each restaurant gets its own realm group (e.g., Best Pizza (ID:1), Not the Best Pizza (ID:2)).
  • Roles = Composite Permission Sets: Create reusable realm-level roles (like Owner, Employee) that bundle granular permissions (e.g., view-order, edit-order).
  • User-Role Assignment = Group-Specific: Assign roles to users within specific restaurant groups so the same user can have different roles across different restaurants.
Step-by-Step Implementation

1. Build Granular Permissions & Composite Roles

First, define the smallest unit of permission, then bundle them into roles that match your user types:

  1. In your Keycloak realm, go to Roles > Realm Roles and create granular permission roles:
    • view-order
    • edit-order
    • delete-order
  2. Create composite roles that represent your user types, combining the permissions they need:
    • Owner: Add view-order, edit-order, delete-order as composite roles
    • Employee: Add view-order as a composite role (you can adjust this later for specific restaurants)
    • Cashier: Add view-order, edit-order (for cases like Jane Doe in your example)

2. Create Restaurant Groups & Assign Group-Specific Roles

Next, model each restaurant as a group, then assign roles to users within those groups:

  1. Go to Groups in your realm, create a group for each restaurant (use the restaurant ID in the name for clarity, e.g., Best Pizza (ID:1)).
  2. For each user:
    • Navigate to their profile → Groups → Select the restaurant group → Click Assign Role
    • Choose the appropriate role (e.g., assign Owner to John Doe in Best Pizza (ID:1), Employee to Mark in the same group)
    • Repeat for other restaurants (e.g., assign Owner to Mark in Not the Best Pizza (ID:2)).

This ensures the user’s role is tied directly to the restaurant context—no more confusion about which role applies where.

3. Configure Client Scopes to Expose Context in Tokens

To make this data usable in your services, you need to include group and role context in the access token. Here’s how:

  1. Go to Client Scopes → Create a custom scope named restaurant-context.
  2. Add two mappers to this scope:
    • Group Membership Mapper: Set the claim name to restaurants, configure it to return group IDs/names (whichever your app uses to identify restaurants). Disable "Full group path" since you don’t need hierarchy.
    • Group Role Mapper: Set the claim name to restaurant_roles, configure it to return roles per group. This will give you a JSON object like:
      "restaurant_roles": {
        "Best Pizza (ID:1)": ["Employee"],
        "Not the Best Pizza (ID:2)": ["Owner"]
      }
      
  3. Attach this custom scope to all your service clients so every login token includes this context.

4. Enforce Permissions in Your Services

Once the token has the restaurant context, your services can validate permissions without calling Keycloak every time. Here’s a quick example in Python:

def has_required_permission(token, restaurant_id, required_permission):
    # Map roles to their allowed permissions (store this in your service config)
    role_permissions = {
        "Owner": ["view-order", "edit-order", "delete-order"],
        "Employee": ["view-order"],
        "Cashier": ["view-order", "edit-order"]
    }
    
    # Get the user's roles for the target restaurant
    restaurant_roles = token.get("restaurant_roles", {}).get(restaurant_id, [])
    
    # Check if any role grants the required permission
    for role in restaurant_roles:
        if required_permission in role_permissions.get(role, []):
            return True
    return False

5. Enable SSO Across Services

SSO works out of the box here—just configure all your services to use the same Keycloak realm. Users log in once, get a token valid for all services, and each service uses the token’s claims to enforce permissions. No extra setup needed!

Why This Works (And Is Maintainable)
  • Simple to Scale: Adding a new restaurant is just creating a group and assigning roles—no complex policy changes.
  • Clear Separation: Permissions are tied to roles, roles are tied to restaurant groups, so you never mix up which user has access where.
  • Low Overhead: All context lives in the token, so your services don’t need to make repeated calls to Keycloak’s API.
  • Flexible: If you need to adjust permissions for a specific restaurant (e.g., let an Employee edit orders), just add the edit-order role to their group assignment.
Alternative to Avoid: Realm Per Restaurant

You might consider using a separate realm for each restaurant, but that’s overkill here. It adds complexity for user management (you’d need federation to share users across realms) and makes SSO harder to implement. Groups are the simpler, more maintainable choice for your scenario.


内容的提问来源于stack exchange,提问作者Pedro Rocha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 16:37:29