Devlet Kimliği için OpenID Connect
SPID ve CIE, OpenID Connect'e doğru evriliyor: İtalyan kimlik sistemleri için Bağlı Tarafın nasıl uygulanacağı, OIDC federasyonunu yapılandırın, güvence düzeylerini (LoA) yönetin, PKCE ve JARM ile akışları güvenli hale getirin ve hazırlık yapın EUDI Cüzdan ekosistemiyle bütünleşmek.
İtalyan Hükümet Kimliğinde OIDC'ye Doğru Evrim
On yıldan fazla bir süredir İtalyan dijital kimliği şu protokole dayanmaktadır: SAML2.0: Sağlam, iyi standardize edilmiş, ancak mobil öncesi dönemde tasarlandı. Akıllı telefonlara yönelik native uygulamaların patlaması ve Tek Sayfa Uygulamaların yaygınlaşmasıyla birlikte, SAML, büyük XML alışverişi, zayıf mobil destek, SPA'lara karmaşık entegrasyon gibi sınırlamalarını gösterdi.
Geçiş OpenID Bağlantısı (OIDC) kaçınılmazdı. Ocak 2023'te AgID şunu yayınladı: SPID'de OpenID Bağlantı Yönergeleri ve CIE'de OpenID Bağlantı YönergeleriOAuth 2.0'ı temel alan standardı, İtalyan hükümeti kimliğinin evriminin bir yolu olarak resmi hale getiriyor. PNRR hedefi, Mart 2026'ya kadar 16.500 İtalyan KA'nın tamamının SPID veya CIE aracılığıyla elektronik kimlik belirlemeyi benimsemesini gerektiriyor.
Neden PA için OpenID Connect ve SAML karşılaştırması
- Hafif jetonlar: XML SAML onayı yerine JWT — yük %60-70 oranında azaltıldı
- Mobil öncelikli: Yerel uygulamalar ve SPA'lar için tasarlanmış PKCE'li OAuth 2.0
- Modern ekosistem: herhangi bir dil/çerçeve için mevcut kütüphaneler
- Standartlaştırılmış federasyon: Otomatik güven zinciri için OpenID Federasyonu 1.0
- EUDI Cüzdanına Doğru: OpenID4VP ve OpenID4VCI aynı OIDC temellerini kullanır
SPID/CIE OIDC Federasyonunun Mimarisi
SPID ve CIE için OIDC federasyonu aşağıdakilere dayanmaktadır: OpenID Federasyonu 1.0zincir yapımını otomatikleştiren bir standart kuruluşlar arasındaki güven. Bu, her SP'nin meta verileri manuel olarak değiştirmek zorunda olduğu SAML meta veri kaydının manuel modelini aşıyor Her IdP ile XML.
Federasyondaki kuruluşlar
- Güven Çapası (TA): AgID, İtalyan federasyonunun güven dayanağıdır. Varlık Yapılandırmasını iyi bilinen uç noktaya yayınlar.
- Orta seviye: Birden fazla RP'yi birleştiren AgID yetkili toplayıcılar (ör. bölgesel KA'lar, belediye toplayıcıları).
- Güvenen Taraf (RP): SPID/CIE OIDC aracılığıyla kullanıcıların kimliğini doğrulayan uygulama.
- Kimlik Sağlayıcı (OP): SPID sağlayıcıları (Poste Italiane, Aruba, InfoCert, vb.) veya İçişleri Bakanlığı'nın CIE IdP'si.
Varlık Yapılandırması ve Güven Zinciri
// Entity Configuration di un Relying Party
// Disponibile al well-known endpoint:
// GET https://my-service.comune.it/.well-known/openid-federation
{
"iss": "https://my-service.comune.it",
"sub": "https://my-service.comune.it",
"iat": 1710000000,
"exp": 1741536000,
"jwks": {
"keys": [
{
"kty": "EC",
"kid": "rp-sig-key-2025",
"crv": "P-256",
"x": "...",
"y": "...",
"use": "sig"
}
]
},
"metadata": {
"openid_relying_party": {
"application_type": "web",
"client_id": "https://my-service.comune.it",
"client_registration_types": ["automatic"],
"redirect_uris": [
"https://my-service.comune.it/callback"
],
"response_types": ["code"],
"grant_types": ["authorization_code"],
"scope": "openid profile email",
"token_endpoint_auth_method": "private_key_jwt",
"id_token_signed_response_alg": "ES256",
"subject_type": "pairwise",
"contacts": ["tech-team@comune.it"]
}
},
"authority_hints": [
"https://registry.spid.gov.it"
]
}
PKCE ile Yetkilendirme Kodu Akışını Uygulama
SPID/CIE OIDC için önerilen akış:PKCE ile Yetkilendirme Kodu Akışı (Kod Değişimi için Kanıt Anahtarı, RFC 7636). PKCE, ele geçirilen yetkilendirme kodlarına karşı koruma sağlar ve mobil uygulamalar için zorunlu olup web uygulamaları için önerilir.
1. Adım: PKCE Oluşturma ve Yetkilendirme Talebi
// TypeScript - Authorization Request con PKCE
import crypto from "crypto";
function generatePKCE() {
// code_verifier: stringa casuale 43-128 caratteri
const codeVerifier = crypto.randomBytes(32)
.toString("base64url");
// code_challenge: SHA256 del verifier, base64url encoded
const codeChallenge = crypto.createHash("sha256")
.update(codeVerifier)
.digest("base64url");
return { codeVerifier, codeChallenge };
}
async function initiateLogin(req: Request, res: Response) {
const { codeVerifier, codeChallenge } = generatePKCE();
const state = crypto.randomBytes(16).toString("base64url");
const nonce = crypto.randomBytes(16).toString("base64url");
// Salva in sessione (server-side)
req.session.pkce = { codeVerifier, state, nonce };
// Costruisci l'Authorization Request
const params = new URLSearchParams({
response_type: "code",
client_id: "https://my-service.comune.it",
redirect_uri: "https://my-service.comune.it/callback",
scope: "openid profile",
// Per SPID LoA 2 (identità verificata con password forte)
acr_values: "https://www.spid.gov.it/SpidL2",
state,
nonce,
code_challenge: codeChallenge,
code_challenge_method: "S256",
// Parametri SPID specifici
prompt: "login",
});
// Scopri il provider selezionato tramite OP Selector o discovery
const opAuthEndpoint = await discoverOPEndpoint("https://idp.poste.it");
res.redirect(`${opAuthEndpoint}?${params.toString()}`);
}
Adım 2: Geri Arama ve Token Değişimi
// TypeScript - Gestione callback e token exchange
async function handleCallback(req: Request, res: Response) {
const { code, state, error } = req.query;
const session = req.session.pkce;
// Verifica state per prevenire CSRF
if (state !== session.state) {
return res.status(400).json({ error: "State mismatch" });
}
if (error) {
return res.status(400).json({ error });
}
// Token Request - usa private_key_jwt per autenticarsi al token endpoint
const clientAssertion = await createClientAssertion({
iss: "https://my-service.comune.it",
sub: "https://my-service.comune.it",
aud: "https://idp.poste.it/oauth/token",
jti: crypto.randomBytes(16).toString("hex"),
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60,
});
const tokenResponse = await fetch("https://idp.poste.it/oauth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code: code as string,
redirect_uri: "https://my-service.comune.it/callback",
client_id: "https://my-service.comune.it",
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_assertion: clientAssertion,
code_verifier: session.codeVerifier,
}),
});
const tokens = await tokenResponse.json();
// Verifica e decodifica l'ID Token
const idToken = await verifyIdToken(tokens.id_token, {
expectedNonce: session.nonce,
expectedAudience: "https://my-service.comune.it",
});
// idToken.sub = identificatore opaco pairwise dell'utente
// idToken.acr = livello di garanzia (LoA) ottenuto
console.log("User authenticated:", idToken.sub);
console.log("LoA achieved:", idToken.acr);
}
SPID ve CIE'de Güvence Düzeyleri (LoA)
Devlet kimliğinin en önemli yönlerinden biri, Güvence Düzeyi (LoA), bu, kimlik doğrulama işleminin ne kadar güvenilir olduğunu gösterir. SPID üç düzeyi tanımlar:
| Seviye | ACR URI'si | Yöntem | Tipik Kullanım |
|---|---|---|---|
| SpidL1 | https://www.spid.gov.it/SpidL1 | Kullanıcı adı + şifre | Düşük riskli hizmetler, hassas olmayan veri danışmanlığı |
| SpidL2 | https://www.spid.gov.it/SpidL2 | Kullanıcı adı + şifre + OTP/push | Standart PA hizmetleri (beyannameler, başvurular, ödemeler) |
| SpidL3 | https://www.spid.gov.it/SpidL3 | Sertifikalı fiziksel cihaz | Yüksek riskli işlemler, nitelikli elektronik imza |
İçin CIE (Elektronik Kimlik Kartı), garanti düzeyi her zaman LoA3'tür (maksimum). Belgenin ve PIN'in fiziksel olarak bulundurulmasını gerektirdiğinden CIE NFC çipini kullandı. Bu, CIE'yi bariz bir seçim haline getiriyor Güçlü kimlik doğrulama gerektiren hizmetler için.
UserInfo Uç Noktası ve SPID/CIE Nitelikleri
Oturum açtıktan sonra İtimat Eden Taraf, Erişim Simgesini kullanarak kullanıcının niteliklerini UserInfo Uç Noktasından alabilir. SPID OIDC'de mevcut olan nitelikler teknik profilde tanımlanmıştır:
// GET /userinfo
// Authorization: Bearer <access_token>
// Risposta UserInfo SPID
{
"sub": "c5d9b2f3-1a4e-4b8d-9f2a-3e5c7d8f9b1a", // pairwise pseudonimo
"https://attributes.spid.gov.it/name": "Mario",
"https://attributes.spid.gov.it/familyName": "Rossi",
"https://attributes.spid.gov.it/fiscalNumber": "RSSMRA90A15H501Z",
"https://attributes.spid.gov.it/dateOfBirth": "1990-01-15",
"https://attributes.spid.gov.it/placeOfBirth": "Roma",
"https://attributes.spid.gov.it/countyOfBirth": "RM",
"https://attributes.spid.gov.it/idCard": "MRTMRA90A15H501Z",
"https://attributes.spid.gov.it/address": {
"formatted": "Via Roma 1, 00100 Roma RM"
},
"https://attributes.spid.gov.it/email": "mario.rossi@example.com",
"https://attributes.spid.gov.it/mobilePhone": "+39 333 1234567",
"acr": "https://www.spid.gov.it/SpidL2"
}
// ATTENZIONE: richiedere solo gli attributi strettamente necessari
// nell'Authorization Request tramite il parametro 'claims':
// "claims": {
// "userinfo": {
// "https://attributes.spid.gov.it/fiscalNumber": {"essential": true},
// "https://attributes.spid.gov.it/name": null
// }
// }
SPID Niteliklerinin Gizliliği ve Minimize Edilmesi
Kullanıcının vergi kodunu gerçek bir ihtiyaç olmadan talep etmek, GDPR'nin en aza indirme ilkesinin ihlalidir. AgID Yönergeleri, talep edilen her özelliğin, hizmet e-postasının belirli işlevselliği tarafından motive edilmesi gerektiğini belirtir. gizlilik politikasında belirtilmiştir. AgID denetimi sırasında istenen özelliklerin gerekçelendirilmemesi, akreditasyonun iptaline yol açabilir.
SPID/CIE OIDC için SDK ve Resmi Kitaplıklar
proje Geliştiriciler İtalya (developers.italia.it) çeşitli dillerde resmi SDK'lar sağlar SPID/CIE OIDC entegrasyonunu basitleştirmek için:
## SDK Ufficiali Developers Italia - SPID/CIE OIDC Federation
# Python (Django)
pip install spid-cie-oidc
# Configurazione in Django settings.py
INSTALLED_APPS = [
...
"spid_cie_oidc.entity",
"spid_cie_oidc.relying_party",
]
OIDCFED_DEFAULT_TRUST_ANCHOR = "https://registry.spid.gov.it"
OIDCFED_IDENTITY_PROVIDERS = {
"spid": "https://registry.spid.gov.it",
"cie": "https://idserver.servizicie.interno.gov.it"
}
# Configura automaticamente gli endpoint di federazione
# e gestisce la trust chain dinamicamente
# Java
# Maven: eu.italia.gov:spid-cie-oidc-java:latest
# .NET
# NuGet: AGID.SPID.OIDC
# Node.js (Express)
npm install spid-cie-oidc-node
# PHP
composer require italia/spid-php-lib
JARM: JWT Tabanlı Yetkilendirme Yanıt Modu
SPID/CIE OIDC Yönergeleri aşağıdakilerin kullanılmasını önerir: JARM (JWT Yetkilendirme Yanıt Modu) korumak
yetkilendirme yanıtı. Geçmek yerine code e state sorgu parametreleri olarak açık metin olarak,
JARM, yanıtı Kimlik Sağlayıcı tarafından imzalanan bir JWT'de kapsüller.
// Authorization Request con JARM
{
"response_type": "code",
"response_mode": "form_post.jwt", // JARM mode
"client_id": "https://my-service.comune.it",
...
}
// Risposta JARM dal IdP (form POST al redirect_uri)
// Il parametro 'response' contiene un JWT firmato:
// Header:
{ "alg": "ES256", "kid": "idp-key-2025" }
// Payload:
{
"iss": "https://idp.poste.it",
"aud": "https://my-service.comune.it",
"code": "SplxlOBeZQQYbYS6WxSbIA",
"state": "af0ifjsldkj",
"iat": 1710000000,
"exp": 1710000180
}
// Vantaggi JARM:
// 1. Autenticità: garantisce che la risposta venga dall'IdP corretto
// 2. Integrità: impossibile modificare code/state in transito
// 3. Non-repudiation: log auditabili con prova crittografica
Oturum Yönetimi ve Token Yenileme
Hükümet kimliğinin kritik bir yönü, oturumların doğru yönetimidir. Özel sektörden farklı olarak PA hizmetleri, oturum süresi ve oturum kapatmayla ilgili katı kısıtlamalara uymalıdır.
// Gestione sessione sicura per servizi PA
interface SessionConfig {
maxAge: number; // durata massima sessione in secondi
inactivityTimeout: number; // timeout per inattività
requireReauth: boolean; // richiede riautenticazione per operazioni critiche
}
// Configurazione raccomandata per servizi PA
const SESSION_CONFIG: SessionConfig = {
maxAge: 3600, // 1 ora massimo (SPID raccomanda max 30 min per L2)
inactivityTimeout: 900, // 15 min di inattività
requireReauth: true // operazioni di firma richiedono nuovo login
};
// Logout corretto: Single Logout (SLO) obbligatorio per SPID
async function handleLogout(req: Request, res: Response) {
const session = req.session;
// 1. Costruisci logout request per l'IdP
const logoutRequest = createSignedLogoutRequest({
iss: "https://my-service.comune.it",
sub: session.userId,
sid: session.idTokenHint, // session ID dal ID Token
aud: session.idpLogoutEndpoint,
post_logout_redirect_uri: "https://my-service.comune.it/logout-complete",
});
// 2. Distruggi la sessione locale prima del redirect
await req.session.destroy();
// 3. Redirect all'IdP per SLO
res.redirect(
`${session.idpLogoutEndpoint}?` +
`id_token_hint=${session.idToken}&` +
`post_logout_redirect_uri=https://my-service.comune.it/logout-complete&` +
`state=${generateState()}`
);
}
AgID ile Akreditasyon ve Uyumluluk
SPID'yi hizmetine entegre etmek için İtimat Eden Tarafın AgID akreditasyon sürecinden geçmesi gerekir. OIDC için basitleştirilmiş prosedür 2023'ten itibaren kullanıma sunulacaktır:
-
Teknik kayıt: Varlık Yapılandırması yapılandırması ve uç nokta doğrulaması
/.well-known/openid-federation. AgID, otomatik araçlar aracılığıyla uyumluluğu doğrular. - Fonksiyonel testler: Doğru uygulamayı doğrulamak için spid-sp-test (açık kaynak Python aracı) kullanma. Araç, Kimlik Sağlayıcıların davranışını simüle eder ve 200'den fazla test senaryosunu doğrular.
- GDPR uyumluluğu: gerekli her SPID özelliği için veri işlemenin belgelenmesi.
- Anlaşmanın imzalanması: SPID Teknik Kurallarının ve üyelik sözleşmesinin kabulü.
## Uso di spid-sp-test per verificare l'implementazione
# Installazione
pip install spid_sp_test
# Verifica metadata OIDC
spid_sp_test \
--metadata-url https://my-service.comune.it/.well-known/openid-federation \
--profile oidc_op
# Test flusso completo (richiede credenziali di test)
spid_sp_test \
--metadata-url https://my-service.comune.it/.well-known/openid-federation \
--authn-url https://my-service.comune.it/login/spid \
--profile oidc_sp_public \
--extra \
--debug
# Output: report HTML con dettagli dei 200+ test
# File: report_<timestamp>.html
Yakınsamaya Doğru: SPID/CIE OIDC ve EUDI Cüzdanı
SAML'den OIDC'ye geçiş nihai hedef değildir. Ekosistem tam entegrasyona doğru ilerliyor ile EUDI Cüzdanı OpenID4VP aracılığıyla. proje iam-proxy-italia GitHub'da zaten gösteriyor bir IAM proxy'sinin aynı anda SAML 2.0, OIDC ve OpenID4VC'yi (IT-Wallet/EUDI Wallet için) nasıl destekleyebileceğini öğrenin.
Modern bir PA hizmeti için ideal mimari, üç akışın tamamını şeffaf bir şekilde desteklemelidir:
// Middleware di autenticazione multi-protocollo
interface AuthProvider {
protocol: "saml2" | "oidc" | "openid4vp";
name: string;
endpoint: string;
}
const AUTH_PROVIDERS: AuthProvider[] = [
{
protocol: "oidc",
name: "SPID",
endpoint: "https://registry.spid.gov.it"
},
{
protocol: "oidc",
name: "CIE",
endpoint: "https://idserver.servizicie.interno.gov.it"
},
{
protocol: "openid4vp",
name: "IT Wallet / EUDI Wallet",
endpoint: "eudi-openid4vp://"
}
];
function selectAuthFlow(userAgent: string, userPreference?: string): AuthProvider {
// Logica di selezione basata su contesto
if (userPreference === "wallet" || hasWalletApp(userAgent)) {
return AUTH_PROVIDERS.find(p => p.protocol === "openid4vp")!;
}
// Default: CIE OIDC (LoA3 per impostazione predefinita)
return AUTH_PROVIDERS.find(p => p.name === "CIE")!;
}
En İyi Uygulamalar ve Anti-Kalıplar
SPID/CIE OIDC için En İyi Uygulamalar
- Web uygulamaları için bile her zaman PKCE'yi kullanın (yerel uygulamalar için zorunludur)
- Yetkilendirme yanıtını korumak için JARM'ı uygulayın
- RP imzalama anahtarlarını her 12 ayda bir (veya daha sık) değiştirin
- Amerika
subdahili tanımlayıcı olarak ikili olarak — asla CF veya e-posta gibi nitelikler içermez - Tek Oturum Kapatmayı (SLO) uygulayın — SPID akreditasyonu için zorunludur
- Güven zincirini 24 saate kadar önbelleğe alın (sonra güncelleyin)
- Varlık Bildiriminin sona erme tarihini izleyin (genellikle 24 saat)
Kaçınılması Gereken Anti-Desenler
- Kimlik Kartını kaydetmeyin
localStorageveya HttpOnly olmayan çerezler - Kullanma
response_mode=query(AMERİKAform_postoform_post.jwt) - Geçerli bir neden olmadan Erişim Simgesini ön uçta göstermeyin
- Gereksiz SPID nitelikleri istemeyin (akreditasyon riski)
- Doğrulamayı göz ardı etmeyin
nonceJeton Kimliğinde - Süresi dolmayan oturumları kullanmayın: PA oturumlarının zaman aşımları olması gerekir
Sonuçlar
OpenID Connect, İtalyan ve Avrupa devlet kimlik doğrulamasının geleceğini temsil ediyor. SAML'den OIDC'ye geçiş bu sadece teknik değil; daha modern bir ekosistemi, daha iyi araçları ve doğal bir yolu da beraberinde getiriyor EUDI Cüzdanı ile kendi kendine egemen kimliğe doğru.
Geliştiriciler bugün SPID/CIE OIDC'yi PKCE, JARM, otomatik federasyon gibi doğru kalıplarla uygulamaya başlıyor. ikili konu — OpenID4VP ve EUDI Cüzdan ile daha sonra entegrasyon için en uygun konumdadır. Bugün iyi yazılan kodun yarın yeniden yazılmasına gerek yoktur: bu, kamu dijital hizmetlerinin sürekliliğine yapılan bir yatırımdır.
GovTech serisi devam ediyor
Bir sonraki makalede Açık Veri API'lerinin tasarımını ve genel verilerin nasıl verimli bir şekilde yayınlanıp tüketileceğini keşfedin.







