Hammad712's picture
Added SSO Backend Functionality
8393a26
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"}