원클릭으로
oidc-hosted-page-python
Implement "Sign in with SSO" in Python Flask applications using SSOJet OIDC Authorization Code flow.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Implement "Sign in with SSO" in Python Flask applications using SSOJet OIDC Authorization Code flow.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Implement Machine-to-Machine (M2M) authentication using SSOJet OAuth2 Client Credentials flow for backend services and daemons.
Implement "Sign in with SSO" in native Android/Kotlin applications using SSOJet OIDC with AppAuth.
Implement "Sign in with SSO" in Angular SPA applications using SSOJet OIDC with PKCE.
Implement "Sign in with SSO" in ASP.NET Core applications using SSOJet OIDC middleware.
Implement "Sign in with SSO" in Go applications using SSOJet OIDC Authorization Code flow.
Implement "Sign in with SSO" in native iOS/Swift applications using SSOJet OIDC with AppAuth.
| name | oidc-hosted-page-python |
| description | Implement "Sign in with SSO" in Python Flask applications using SSOJet OIDC Authorization Code flow. |
This expert AI assistant guide walks you through integrating "Sign in with SSO" functionality into an existing login page in a Python Flask application using SSOJet as an OIDC identity provider. The goal is to modify the existing login flow to add SSO support without disrupting the current traditional login functionality (e.g., email/password).
authlib, flask, python-dotenv.http://localhost:5000/auth/callback).Run the following command to install the required libraries:
pip install authlib flask python-dotenv requests
Create a .env file in the project root:
SSOJET_ISSUER_URL=https://auth.ssojet.com
SSOJET_CLIENT_ID=your_client_id
SSOJET_CLIENT_SECRET=your_client_secret
SSOJET_REDIRECT_URI=http://localhost:5000/auth/callback
FLASK_SECRET_KEY=a_strong_random_secret
Create a dedicated utility file for OIDC configuration (e.g., lib/oidc.py):
# lib/oidc.py
import os
from authlib.integrations.flask_client import OAuth
oauth = OAuth()
def init_oauth(app):
"""Initialize the OAuth registry with the SSOJet provider."""
oauth.init_app(app)
oauth.register(
name='ssojet',
client_id=os.getenv('SSOJET_CLIENT_ID'),
client_secret=os.getenv('SSOJET_CLIENT_SECRET'),
server_metadata_url=f"{os.getenv('SSOJET_ISSUER_URL')}/.well-known/openid-configuration",
client_kwargs={
'scope': 'openid profile email',
},
)
Modify your existing login template (e.g., templates/login.html) to include the "Sign in with SSO" toggle:
<!-- templates/login.html -->
<!DOCTYPE html>
<html>
<head><title>Sign In</title></head>
<body>
<div class="login-container">
<h1>Sign In</h1>
{% if error %}
<p style="color: red;">{{ error }}</p>
{% endif %}
<form id="loginForm" method="POST" action="/auth/login">
<div>
<label for="email">Email</label>
<input type="email" id="email" name="email" required />
</div>
<div id="passwordField">
<label for="password">Password</label>
<input type="password" id="password" name="password" required />
</div>
<input type="hidden" id="isSSO" name="is_sso" value="false" />
<button type="submit" id="submitBtn">Sign In</button>
</form>
<button type="button" id="ssoToggle" onclick="toggleSSO()">
Sign in with SSO
</button>
</div>
<script>
function toggleSSO() {
const isSSO = document.getElementById('isSSO');
const passwordField = document.getElementById('passwordField');
const submitBtn = document.getElementById('submitBtn');
const ssoToggle = document.getElementById('ssoToggle');
if (isSSO.value === 'false') {
isSSO.value = 'true';
passwordField.style.display = 'none';
document.getElementById('password').removeAttribute('required');
submitBtn.textContent = 'Continue with SSO';
ssoToggle.textContent = 'Back to Password Login';
} else {
isSSO.value = 'false';
passwordField.style.display = 'block';
document.getElementById('password').setAttribute('required', 'true');
submitBtn.textContent = 'Sign In';
ssoToggle.textContent = 'Sign in with SSO';
}
}
</script>
</body>
</html>
Create the necessary routes to handle the OIDC flow.
1. Main Application Setup (app.py):
# app.py
import os
import secrets
from dotenv import load_dotenv
from flask import Flask, redirect, url_for, session, render_template, request
from lib.oidc import oauth, init_oauth
load_dotenv()
app = Flask(__name__)
app.secret_key = os.getenv('FLASK_SECRET_KEY')
# Initialize OAuth
init_oauth(app)
@app.route('/login')
def login_page():
error = request.args.get('error')
return render_template('login.html', error=error)
@app.route('/auth/login', methods=['POST'])
def login():
email = request.form.get('email')
is_sso = request.form.get('is_sso')
if is_sso == 'true':
# Generate a random state for CSRF protection
state = secrets.token_urlsafe(16)
session['oidc_state'] = state
redirect_uri = os.getenv('SSOJET_REDIRECT_URI')
return oauth.ssojet.authorize_redirect(
redirect_uri,
login_hint=email,
state=state,
)
# Existing password login logic here
print('Processing traditional login...')
return redirect('/dashboard')
@app.route('/auth/callback')
def callback():
try:
# Verify state
stored_state = session.pop('oidc_state', None)
received_state = request.args.get('state')
if stored_state != received_state:
return redirect('/login?error=state_mismatch')
token = oauth.ssojet.authorize_access_token()
userinfo = token.get('userinfo')
if not userinfo:
userinfo = oauth.ssojet.userinfo()
# TODO: Create a session for the user based on `userinfo`
session['user'] = dict(userinfo)
print('Authenticated User:', userinfo)
# Redirect to the dashboard or intended page
return redirect('/dashboard')
except Exception as e:
print(f'OIDC Callback Error: {e}')
return redirect('/login?error=oidc_failed')
@app.route('/dashboard')
def dashboard():
user = session.get('user')
if not user:
return redirect('/login')
return f"<h1>Dashboard</h1><pre>{user}</pre><a href='/auth/logout'>Logout</a>"
@app.route('/auth/logout')
def logout():
session.clear()
return redirect('/login')
if __name__ == '__main__':
app.run(debug=True, port=5000)
python app.py.http://localhost:5000/login)./auth/callback and then to /dashboard.flask-session) and serve over HTTPS..env to source control. Use secrets management in production.