add admin route for admin consent
This commit is contained in:
parent
3cb6fb2544
commit
38df33fd37
2 changed files with 195 additions and 0 deletions
121
AZURE_AD_CONSENT_LINKS.md
Normal file
121
AZURE_AD_CONSENT_LINKS.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Azure AD Consent Links
|
||||
|
||||
## Konfiguration
|
||||
- **Client ID**: `c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`
|
||||
- **Tenant ID**: `common` (Multi-Tenant)
|
||||
- **Redirect URI (Prod)**: `https://gateway-prod.poweron-center.net/api/msft/auth/callback`
|
||||
- **Redirect URI (Int)**: `https://gateway-int.poweron-center.net/api/msft/auth/callback`
|
||||
|
||||
## Berechtigungen (Scopes)
|
||||
- `Mail.ReadWrite` - E-Mails lesen und schreiben
|
||||
- `Mail.Send` - E-Mails senden
|
||||
- `Mail.ReadWrite.Shared` - Zugriff auf geteilte Postfächer
|
||||
- `User.Read` - Benutzerprofil lesen
|
||||
- `Sites.ReadWrite.All` - Alle SharePoint-Standorte lesen und schreiben
|
||||
- `Files.ReadWrite.All` - Alle Dateien lesen und schreiben
|
||||
|
||||
## Admin Consent Link (für Tenant-Administrator)
|
||||
|
||||
**WICHTIG:** Der Admin Consent Endpoint gibt `admin_consent` und `tenant` zurück, nicht `code` und `state`.
|
||||
Der bestehende `/auth/callback` Handler erwartet `code` und `state` für den normalen OAuth-Flow.
|
||||
|
||||
**Option 1: Admin Consent über Azure Portal (für eigenen Tenant)**
|
||||
1. Gehe zu Azure Portal → Azure Active Directory → App registrations
|
||||
2. Wähle die App `c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`
|
||||
3. Gehe zu "API permissions"
|
||||
4. Klicke auf "Grant admin consent for [Tenant Name]"
|
||||
|
||||
**Option 1b: App für andere Tenants verfügbar machen**
|
||||
|
||||
Um die App für andere Tenants sichtbar zu machen, müssen folgende Schritte durchgeführt werden:
|
||||
|
||||
1. **Multi-Tenant Konfiguration prüfen:**
|
||||
- Azure Portal → Azure Active Directory → App registrations
|
||||
- Wähle die App `c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`
|
||||
- Gehe zu "Authentication"
|
||||
- Stelle sicher, dass "Supported account types" auf **"Accounts in any organizational directory and personal Microsoft accounts"** oder **"Accounts in any organizational directory"** gesetzt ist
|
||||
|
||||
2. **App für andere Tenants verfügbar machen:**
|
||||
|
||||
**Methode A: Direkter Admin Consent Link (empfohlen)**
|
||||
- Andere Tenant-Administratoren können den Admin Consent Link verwenden:
|
||||
```
|
||||
https://login.microsoftonline.com/{TENANT_ID}/adminconsent?client_id=c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c&redirect_uri=https://gateway-prod.poweron-center.net/api/msft/adminconsent/callback
|
||||
```
|
||||
- Ersetze `{TENANT_ID}` durch die Tenant-ID des Ziel-Tenants (oder verwende `common` für Multi-Tenant)
|
||||
|
||||
**Methode B: Manuell über Azure Portal (für andere Tenants)**
|
||||
- Tenant-Administrator des anderen Tenants:
|
||||
1. Gehe zu Azure Portal → Azure Active Directory → Enterprise applications
|
||||
2. Klicke auf "+ New application"
|
||||
3. Wähle "Browse Azure AD Gallery" (optional) oder "Create your own application"
|
||||
4. Wenn nicht in Gallery: Wähle "Non-gallery application"
|
||||
5. Gib die Client ID ein: `c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`
|
||||
6. Oder verwende direkt diesen Link:
|
||||
```
|
||||
https://portal.azure.com/#blade/Microsoft_AAD_IAM/ManagedAppMenuBlade/Overview/objectId/{CLIENT_ID}
|
||||
```
|
||||
(Ersetze `{CLIENT_ID}` mit `c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`)
|
||||
7. Gehe zu "Permissions" → "Grant admin consent"
|
||||
|
||||
**Methode C: App in Azure AD Gallery veröffentlichen (optional)**
|
||||
- Für größere Sichtbarkeit kann die App in der Azure AD App Gallery veröffentlicht werden
|
||||
- Azure Portal → App registrations → App → "Branding & properties"
|
||||
- Kontaktiere Microsoft für Gallery-Veröffentlichung
|
||||
|
||||
3. **Wichtig für Multi-Tenant Apps:**
|
||||
- Die Redirect URIs müssen öffentlich erreichbar sein
|
||||
- Die App muss die richtigen Berechtigungen deklarieren
|
||||
- Tenant-Administratoren müssen explizit zustimmen (Admin Consent)
|
||||
|
||||
**Option 2: Admin Consent Link (mit Callback-Handler)**
|
||||
### Production
|
||||
```
|
||||
https://login.microsoftonline.com/common/adminconsent?client_id=c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c&redirect_uri=https://gateway-prod.poweron-center.net/api/msft/adminconsent/callback
|
||||
```
|
||||
|
||||
### Integration
|
||||
```
|
||||
https://login.microsoftonline.com/common/adminconsent?client_id=c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c&redirect_uri=https://gateway-int.poweron-center.net/api/msft/adminconsent/callback
|
||||
```
|
||||
|
||||
**Hinweis:** Der `/adminconsent/callback` Endpoint ist implementiert und verarbeitet die `admin_consent` und `tenant` Parameter. Nach erfolgreichem Admin Consent wird eine Bestätigungsseite angezeigt.
|
||||
|
||||
## User Consent Link (für einzelne Benutzer)
|
||||
|
||||
### Production
|
||||
```
|
||||
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c&response_type=code&redirect_uri=https://gateway-prod.poweron-center.net/api/msft/auth/callback&response_mode=query&scope=Mail.ReadWrite Mail.Send Mail.ReadWrite.Shared User.Read Sites.ReadWrite.All Files.ReadWrite.All offline_access openid profile&state=login
|
||||
```
|
||||
|
||||
### Integration
|
||||
```
|
||||
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c&response_type=code&redirect_uri=https://gateway-int.poweron-center.net/api/msft/auth/callback&response_mode=query&scope=Mail.ReadWrite Mail.Send Mail.ReadWrite.Shared User.Read Sites.ReadWrite.All Files.ReadWrite.All offline_access openid profile&state=login
|
||||
```
|
||||
|
||||
## Hinweise
|
||||
|
||||
1. **Admin Consent**: Muss von einem Tenant-Administrator durchgeführt werden, um die App für alle Benutzer im Tenant zu genehmigen
|
||||
2. **User Consent**: Jeder Benutzer kann individuell zustimmen (wenn Admin Consent nicht durchgeführt wurde)
|
||||
3. **Multi-Tenant**: Da `common` als Tenant verwendet wird, funktioniert die App für alle Azure AD Tenants
|
||||
4. **Redirect URI**: Muss exakt in der Azure AD App-Registrierung konfiguriert sein
|
||||
|
||||
## Azure Portal Konfiguration
|
||||
|
||||
Stelle sicher, dass in der Azure AD App-Registrierung (`c7e7112d-61dc-4f3a-8cd3-08cc4cd7504c`) folgendes konfiguriert ist:
|
||||
|
||||
1. **Redirect URIs**:
|
||||
- `https://gateway-prod.poweron-center.net/api/msft/auth/callback`
|
||||
- `https://gateway-int.poweron-center.net/api/msft/auth/callback`
|
||||
|
||||
2. **API Permissions** (Delegated):
|
||||
- ✅ Mail.ReadWrite
|
||||
- ✅ Mail.Send
|
||||
- ✅ Mail.ReadWrite.Shared
|
||||
- ✅ User.Read
|
||||
- ✅ Sites.ReadWrite.All
|
||||
- ✅ Files.ReadWrite.All
|
||||
|
||||
3. **Supported account types**:
|
||||
- "Accounts in any organizational directory and personal Microsoft accounts" (Multi-tenant)
|
||||
|
||||
|
|
@ -132,6 +132,80 @@ async def login(
|
|||
detail=f"Failed to initiate Microsoft login: {str(e)}"
|
||||
)
|
||||
|
||||
@router.get("/adminconsent/callback")
|
||||
async def adminconsent_callback(
|
||||
admin_consent: Optional[str] = Query(None),
|
||||
tenant: Optional[str] = Query(None),
|
||||
error: Optional[str] = Query(None),
|
||||
error_description: Optional[str] = Query(None),
|
||||
request: Request = None
|
||||
) -> HTMLResponse:
|
||||
"""Handle Microsoft Admin Consent callback"""
|
||||
try:
|
||||
if error:
|
||||
logger.error(f"Admin consent error: {error} - {error_description}")
|
||||
return HTMLResponse(
|
||||
content=f"""
|
||||
<html>
|
||||
<head><title>Admin Consent Failed</title></head>
|
||||
<body>
|
||||
<h1>Admin Consent Failed</h1>
|
||||
<p>Error: {error}</p>
|
||||
<p>Description: {error_description or 'No description provided'}</p>
|
||||
<p>Please contact your administrator.</p>
|
||||
</body>
|
||||
</html>
|
||||
""",
|
||||
status_code=400
|
||||
)
|
||||
|
||||
if admin_consent == "True" and tenant:
|
||||
logger.info(f"Admin consent granted for tenant: {tenant}")
|
||||
return HTMLResponse(
|
||||
content=f"""
|
||||
<html>
|
||||
<head><title>Admin Consent Successful</title></head>
|
||||
<body>
|
||||
<h1>Admin Consent Successful</h1>
|
||||
<p>The application has been granted admin consent for tenant: <strong>{tenant}</strong></p>
|
||||
<p>All users in this tenant can now use the application without individual consent.</p>
|
||||
<p>You can close this window.</p>
|
||||
<script>
|
||||
setTimeout(() => window.close(), 3000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
)
|
||||
else:
|
||||
logger.warning(f"Admin consent callback received unexpected parameters: admin_consent={admin_consent}, tenant={tenant}")
|
||||
return HTMLResponse(
|
||||
content=f"""
|
||||
<html>
|
||||
<head><title>Admin Consent Status</title></head>
|
||||
<body>
|
||||
<h1>Admin Consent Status</h1>
|
||||
<p>Admin Consent: {admin_consent or 'Not provided'}</p>
|
||||
<p>Tenant: {tenant or 'Not provided'}</p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in admin consent callback: {str(e)}", exc_info=True)
|
||||
return HTMLResponse(
|
||||
content=f"""
|
||||
<html>
|
||||
<head><title>Admin Consent Error</title></head>
|
||||
<body>
|
||||
<h1>Error Processing Admin Consent</h1>
|
||||
<p>{str(e)}</p>
|
||||
</body>
|
||||
</html>
|
||||
""",
|
||||
status_code=500
|
||||
)
|
||||
|
||||
@router.get("/auth/callback")
|
||||
async def auth_callback(code: str, state: str, request: Request, response: Response) -> HTMLResponse:
|
||||
"""Handle Microsoft OAuth callback"""
|
||||
|
|
|
|||
Loading…
Reference in a new issue