File size: 2,078 Bytes
8393a26 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
from fastapi import APIRouter, Request, HTTPException
from authlib.integrations.starlette_client import OAuth
from app.core.config import settings
router = APIRouter()
# Initialize OAuth
oauth = OAuth()
# Register Microsoft Provider
# We use the tenant-specific endpoint for better security and internal organization
CONF_URL = f"https://login.microsoftonline.com/{settings.MS_TENANT_ID}/v2.0/.well-known/openid-configuration"
oauth.register(
name='microsoft',
client_id=settings.MS_CLIENT_ID,
client_secret=settings.MS_CLIENT_SECRET,
server_metadata_url=CONF_URL,
client_kwargs={
'scope': 'openid email profile User.Read'
}
)
@router.get("/login")
async def login(request: Request):
"""
Redirects the user to the Microsoft Login page.
"""
redirect_uri = settings.MS_REDIRECT_URI
return await oauth.microsoft.authorize_redirect(request, redirect_uri)
@router.get("/callback")
async def auth_callback(request: Request):
"""
Handles the callback from Microsoft after successful login.
Exchanges the authorization code for an access token and user info.
"""
try:
token = await oauth.microsoft.authorize_access_token(request)
user = token.get('userinfo')
if not user:
# Sometimes userinfo is not directly in the token depending on claims,
# allow fetch via userinfo endpoint if configured, or parse id_token
user = await oauth.microsoft.userinfo(token=token)
# Store user info in session (cookie)
# In a real app, you might issue your own JWT here instead
request.session['user'] = dict(user)
return {"message": "Login successful", "user": user}
except Exception as e:
# Log the error in production
raise HTTPException(status_code=400, detail=f"SSO Login Failed: {str(e)}")
@router.get("/logout")
async def logout(request: Request):
"""
Clears the local session.
"""
request.session.pop('user', None)
return {"message": "Logged out successfully"} |