Atis.Identity.Sso 2.0.0-preview.4

This is a prerelease version of Atis.Identity.Sso.
dotnet add package Atis.Identity.Sso --version 2.0.0-preview.4
                    
NuGet\Install-Package Atis.Identity.Sso -Version 2.0.0-preview.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Atis.Identity.Sso" Version="2.0.0-preview.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Atis.Identity.Sso" Version="2.0.0-preview.4" />
                    
Directory.Packages.props
<PackageReference Include="Atis.Identity.Sso" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Atis.Identity.Sso --version 2.0.0-preview.4
                    
#r "nuget: Atis.Identity.Sso, 2.0.0-preview.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Atis.Identity.Sso@2.0.0-preview.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Atis.Identity.Sso&version=2.0.0-preview.4&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Atis.Identity.Sso&version=2.0.0-preview.4&prerelease
                    
Install as a Cake Tool

Atis.Identity.Sso

ATIS MVC WebUI-lərini atis-service-user-in OpenIddict serverinə OIDC relying party (RP) kimi qoşan paket. Servis protokolu görmür: bir qeydiyyat çağırışı + bir endpoint çağırışı.

// Program.cs
builder.ConfigureAtisSerilog();
builder.Services.AddAtisWebUiHost(builder.Configuration, Assembly.GetExecutingAssembly());
builder.Services.AddAtisSsoRelyingParty(builder.Configuration, o => o.AddPermissionPolicies(StaffPermissions.All));

var app = builder.Build();
app.UseAtisWebUiHost();            // routing → authentication → authorization → session
app.MapAtisSso();                  // /account/login, /account/logout
app.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
app.Run();
"Sso": {
  "Authority": "https://user.atis.edu.az",
  "ClientId": "atis-staff",
  "ClientSecret": "<secret store-dan — appsettings.json-a YAZILMIR>",
  "DataProtection": { "ApplicationName": "atis-staff", "RedisConnection": "redis:6379" }
}

Nə qurulur

Hissə Dəyər Niyə
Sxemlər default/sign-in/sign-out = Cookies, challenge = OpenIdConnect Standart "cookie + oidc" RP: sessiya lokal cookie-dədir, [Authorize] OIDC axınını başladır
Cookie Atis.Sso, HttpOnly, SameSite=Lax, Secure=SameAsRequest, sürüşən 60 dəq (CookieExpireMinutes) Proxy arxasında plain HTTP konteyner (ForwardedHeaders IsHttps-i düzəldir)
OIDC authorization code + PKCE (S256), response_mode=query, SaveTokens=true, RequireHttpsMetadata=true Spec §5.1; token-lər HttpContext.GetTokenAsync("access_token") ilə servis API-lərinə ötürülür
Claim-lər MapInboundClaims=false, NameClaimType="name", RoleClaimType="role" Atis.Identity.Token oxuyucuları xam OIDC adlarını gözləyir (sub, role, UserKey.*)
Userinfo GetClaimsFromUserInfoEndpoint=true; permission[], role[], UserKey.* yalnız çatışmayanlar əlavə olunur Server permission-ı id token-ə YAZMIR (yalnız access token + userinfo); id token-dəki role təkrarlanmır
İcazə AddAtisAuthorization(policies) → fail-closed PermissionAuthorizationHandler, ICurrentUser Policy-siz RP-də [Authorize(Policy=…)] ilk sorğuda sınardı — ona görə policies null → InvalidOperationException
Scope-lar openid profile email roles atis (defolt) atis = UserKey.* id token-ə, permission userinfo-ya; offline_access lazımdırsa Sso:Scopes-da açıq yaz
Access denied AccessDeniedPath boş → 403 status (redirect yox) RP-lərdə /Account/AccessDenied səhifəsi yoxdur
Callback xətası log + RemoteFailurePath (/) ?ssoError=cancelled\|failed Ləğv edilmiş login / itmiş correlation cookie 500 səhifəsi verməsin; ləğv Warning, qalanı Error (konfiq səhvi alert-ə düşür). RemoteFailurePath anonim səhifə olmalıdır — [Authorize] səhifə hər dəfə sınan callback ilə redirect döngəsi yaradır

Sso:Scopes yazılanda defoltu əvəz edir (ASP.NET Core binder-i massivə əlavə etdiyi üçün xassənin defoltu boşdur; openid mütləqdir, validator yoxlayır).

Endpoint-lər (MapAtisSso)

  • GET /account/login?returnUrl=/staff — OIDC challenge, sonda returnUrl-ə qayıdır. Yalnız kökə nisbi lokal yol (/x) qəbul olunur; //evil, mütləq URL → / (open redirect yoxdur).
  • GET|POST /account/logout — lokal cookie silinir, server-də /connect/logout (id_token_hint saxlanılan id token-dən, post_logout_redirect_uri = SignedOutCallbackPath) → SignedOutRedirectPath (/).

OpenIddict tərəfində client belə qeyd olunur (atis-service-user OpenIddict:Clients[]): Type: code, RedirectUris: ["https://staff.atis.edu.az/signin-oidc"], PostLogoutRedirectUris: ["https://staff.atis.edu.az/signout-callback-oidc"], Scopes: ["openid","profile","email","roles","atis"].

Sso bölməsi

Açar Defolt Qeyd
Authority — mütləq, mütləq http(s) URI; http yalnız RequireHttpsMetadata=false ilə
ClientId / ClientSecret — mütləq; secret yalnız secret store/env-dən
Scopes[] openid profile email roles atis openid mütləq
CookieName / CookieExpireMinutes Atis.Sso / 60
CallbackPath / SignedOutCallbackPath /signin-oidc / /signout-callback-oidc kökə nisbi, fərqli
SignedOutRedirectPath / RemoteFailurePath / / / kökə nisbi; RemoteFailurePath anonim olmalıdır (?ssoError= markeri gəlir)
AccessDeniedPath boş (→ 403) verilibsə cookie defolt redirect-i
RequireHttpsMetadata / SaveTokens true / true
DataProtection:ApplicationName boş verilibsə SetApplicationName; Redis ilə mütləq
DataProtection:RedisConnection boş verilibsə açarlar Redis-də DataProtection-Keys:<ApplicationName>; bağlantı ilk açar istifadəsində açılır (start-da yox)

Bütün açarlar ValidateOnStart() ilə host qalxanda yoxlanılır — səhv konfiq OptionsValidationException verir.

Testdə RP-ni qurmaq

Backchannel (discovery/jwks/token/userinfo) in-process serverə yönləndirilir — Configure ilə, PostConfigure ilə yox (handler Backchannel HttpClient-i post-configure mərhələsində BackchannelHttpHandler-dən qurur):

services.Configure<OpenIdConnectOptions>(AtisSsoDefaults.OidcScheme, o => o.BackchannelHttpHandler = serverHandler);

Paketin öz testləri (tests/Atis.Identity.Sso.Tests) stub OIDC server (RS256, PKCE yoxlanır) ilə tam axını — challenge parametrləri, id token + userinfo birləşməsi, fail-closed policy, ICurrentUser, logout id_token_hint, userinfo xətası, AddAtisWebUiHost ilə kompozisiya — pin edir. Real OpenIddict serverinə qarşı eyni axın atis-service-user-in tests/Services.Tests/Sso dəstində sübut olunub.

Bilinən məhdudiyyətlər və qaydalar

  • AddAtisSsoRelyingParty-dən sonra AddAuthentication(...) çağırma — tək-arqumentli overload DefaultScheme-i dəyişir, cookie principal oxunmur və hər səhifə anonim olur. AddAtisApiHost (JWT bearer) ilə eyni prosesdə birləşdirmə: API və WebUI ayrı proseslərdir (spec §4); birləşdirsən eyni Sso bölməsi Audience tələb edib start-da sınar.
  • SaveTokens və token ömrü: cookie sürüşən (60 dəq), saxlanılan access_token isə server ömrü ilə (OpenIddict defoltu ~1 saat) bitir və defolt scope-larda refresh token yoxdur. Servis API-lərini cookie sessiyasından çağırırsansa ya Sso:Scopes-a offline_access əlavə edib yeniləməni özün qur, ya da CookieExpireMinutes-i access token ömründən qısa saxla.
  • Logout GET-dir (ATIS Core ilə eyni): zərərli səhifədən top-level naviqasiya ilə məcburi çıxış mümkündür — təsiri yalnız narahatlıqdır (məlumat sızması/sessiya oğurluğu yoxdur). Təsdiq səhifəsi istəyən servis öz POST endpoint-ini map edir.
  • Cookie ticket-i permission[] claim-lərini daşıyır: çoxlu icazəsi olan istifadəçidə cookie chunk-lanır (ASP.NET Core bunu özü edir, 4 KB-lıq hissələr). Böyüklük problem olarsa ITicketStore (server tərəfi sessiya) növbəti addımdır — paket hazırda qurmur.
  • İstifadəçi kimliyi (sub, UserKey.UserId) yalnız imzalanmış id token-dən gəlir; userinfo onu dəyişə bilmir (framework sub-u tutuşdurur, UserId userinfo siyahısında deyil).
  • Userinfo çağırışı hər login-də bir dəfədir; cookie ömrü boyunca icazə dəyişikliyi görünmür (ATIS Core-un mövcud cookie davranışı ilə eyni). Anında ləğv lazımdırsa cookie ömrünü qısalt.
  • Events bütövlükdə əvəz edilsə (EventsType) paketin OnRemoteFailure-u itir — öz event sinfini ondan törət.
  • Redis key ring real Redis ilə yoxlanmayıb (test mühitində Redis yoxdur); ApplicationName qaydası, qeydiyyat və "əlçatmaz Redis host-un qalxmasına mane olmur" yoxlanıb. Bağlantı AbortOnConnectFail=false ilə açılır və uğursuz cəhd keşlənmir — Redis qayıdan kimi açarlar oxunur (o vaxta qədər autentifikasiyalı sorğular 500 verir).
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0-preview.4 83 9/14/2026

2.0.0-preview.3: ilk buraxılış — legacy gRPC/Microsoft.Identity.Web fork-unu əvəz edir. AddAtisSsoRelyingParty (Sso bölməsi, start-da validasiya, cookie "Atis.Sso" + OIDC code+PKCE, MapInboundClaims=false, name/role claim tipləri, SaveTokens, userinfo-dan permission/role/UserKey.* claim-ləri), MapAtisSso (/account/login, /account/logout), opsional DataProtection tətbiq adı və Redis key ring.