[{"data":1,"prerenderedAt":592},["ShallowReactive",2],{"navigation":3,"\u002Fcomposables\u002Frequirements":203,"\u002Fcomposables\u002Frequirements-surround":587},[4,33,96,114,177],{"title":5,"path":6,"stem":7,"children":8,"icon":32},"Get started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,12,17,22,27],{"title":10,"path":6,"stem":7,"icon":11},"Introduction","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Install AuthEndpoints","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-play",{"title":23,"path":24,"stem":25,"icon":26},"Choose a sign-in stack","\u002Fgetting-started\u002Fchoose-a-sign-in-stack","1.getting-started\u002F4.choose-a-sign-in-stack","i-lucide-signpost",{"title":28,"path":29,"stem":30,"icon":31},"Use the AuthEndpoints skill with coding agents","\u002Fgetting-started\u002Fai-agents","1.getting-started\u002F5.ai-agents","i-lucide-bot","i-lucide-rocket",{"title":34,"path":35,"stem":36,"children":37,"icon":95},"Guides","\u002Fguides","2.guides\u002F01.index",[38,40,45,50,55,60,65,70,75,80,85,90],{"title":34,"path":35,"stem":36,"icon":39},"i-lucide-list-checks",{"title":41,"path":42,"stem":43,"icon":44},"Register users","\u002Fguides\u002Fregistration","2.guides\u002F02.registration","i-lucide-user-plus",{"title":46,"path":47,"stem":48,"icon":49},"Sign users in","\u002Fguides\u002Fsign-in","2.guides\u002F03.sign-in","i-lucide-log-in",{"title":51,"path":52,"stem":53,"icon":54},"Sign users out","\u002Fguides\u002Fsign-out","2.guides\u002F04.sign-out","i-lucide-log-out",{"title":56,"path":57,"stem":58,"icon":59},"Turn on two-factor authentication","\u002Fguides\u002Ftwo-factor","2.guides\u002F05.two-factor","i-lucide-smartphone",{"title":61,"path":62,"stem":63,"icon":64},"Reset a forgotten password","\u002Fguides\u002Freset-password","2.guides\u002F06.reset-password","i-lucide-key-round",{"title":66,"path":67,"stem":68,"icon":69},"Change a user's email or password","\u002Fguides\u002Fmanage-account","2.guides\u002F07.manage-account","i-lucide-user-cog",{"title":71,"path":72,"stem":73,"icon":74},"Add, rename, and remove passkeys","\u002Fguides\u002Fmanage-passkeys","2.guides\u002F08.manage-passkeys","i-lucide-scan-face",{"title":76,"path":77,"stem":78,"icon":79},"Link and unlink GitHub or Google accounts","\u002Fguides\u002Flink-external-accounts","2.guides\u002F09.link-external-accounts","i-lucide-link",{"title":81,"path":82,"stem":83,"icon":84},"Require step-up before sensitive actions","\u002Fguides\u002Fstep-up","2.guides\u002F10.step-up","i-lucide-shield-check",{"title":86,"path":87,"stem":88,"icon":89},"Call the API from a browser","\u002Fguides\u002Fbrowser-clients","2.guides\u002F11.browser-clients","i-lucide-globe",{"title":91,"path":92,"stem":93,"icon":94},"Prepare for production","\u002Fguides\u002Fproduction","2.guides\u002F12.production","i-lucide-factory","i-lucide-waypoints",{"title":97,"path":98,"stem":99,"children":100,"icon":113},"Composable endpoints","\u002Fcomposables","3.composables\u002F1.index",[101,104,108],{"title":102,"path":98,"stem":99,"icon":103},"How composition works","i-lucide-layout-grid",{"title":105,"path":106,"stem":107,"icon":39},"Composition requirements","\u002Fcomposables\u002Frequirements","3.composables\u002F2.requirements",{"title":109,"path":110,"stem":111,"icon":112},"Compose a custom auth stack","\u002Fcomposables\u002Frecipes","3.composables\u002F3.recipes","i-lucide-book-marked","i-lucide-blocks",{"title":115,"icon":116,"path":117,"stem":118,"children":119,"page":176},"Reference","i-lucide-book-open","\u002Fmodules","4.modules",[120,125,129,134,139,144,148,153,157,162,166,171],{"title":121,"path":122,"stem":123,"icon":124},"Endpoint reference","\u002Fmodules\u002Fendpoints","4.modules\u002F01.endpoints","i-lucide-route",{"title":126,"path":127,"stem":128,"icon":69},"Identity management module","\u002Fmodules\u002Fidentity-management","4.modules\u002F02.identity-management",{"title":130,"path":131,"stem":132,"icon":133},"Cookie sign-in module","\u002Fmodules\u002Fcookie-auth","4.modules\u002F03.cookie-auth","i-lucide-cookie",{"title":135,"path":136,"stem":137,"icon":138},"Identity bearer sign-in module","\u002Fmodules\u002Fbearer-auth","4.modules\u002F04.bearer-auth","i-lucide-key",{"title":140,"path":141,"stem":142,"icon":143},"JWT module","\u002Fmodules\u002Fjwt","4.modules\u002F05.jwt","i-lucide-fingerprint",{"title":145,"path":146,"stem":147,"icon":74},"Passkeys module","\u002Fmodules\u002Fpasskeys","4.modules\u002F06.passkeys",{"title":149,"path":150,"stem":151,"icon":152},"ReAuth module","\u002Fmodules\u002Freauth","4.modules\u002F07.reauth","i-lucide-shield-alert",{"title":154,"path":155,"stem":156,"icon":49},"External OAuth packages","\u002Fmodules\u002Fexternal-oauth","4.modules\u002F08.external-oauth",{"title":158,"path":159,"stem":160,"icon":161},"Configuration options","\u002Fmodules\u002Fconfiguration","4.modules\u002F09.configuration","i-lucide-settings",{"title":163,"path":164,"stem":165,"icon":84},"Antiforgery (CSRF) rules","\u002Fmodules\u002Fcsrf","4.modules\u002F10.csrf",{"title":167,"path":168,"stem":169,"icon":170},"Responses and errors","\u002Fmodules\u002Ferrors","4.modules\u002F11.errors","i-lucide-circle-alert",{"title":172,"path":173,"stem":174,"icon":175},"Rate-limit policies","\u002Fmodules\u002Frate-limits","4.modules\u002F12.rate-limits","i-lucide-gauge",false,{"title":178,"icon":179,"path":180,"stem":181,"children":182,"page":176},"Concepts","i-lucide-lightbulb","\u002Fconcepts","5.concepts",[183,188,193,198],{"title":184,"path":185,"stem":186,"icon":187},"AuthEndpoints compared with other options","\u002Fconcepts\u002Fcompare","5.concepts\u002F1.compare","i-lucide-git-compare",{"title":189,"path":190,"stem":191,"icon":192},"Stock Identity endpoints vs AuthEndpoints","\u002Fconcepts\u002Fstock-identity-vs-authendpoints","5.concepts\u002F2.stock-identity-vs-authendpoints","i-lucide-columns-2",{"title":194,"path":195,"stem":196,"icon":197},"Security model","\u002Fconcepts\u002Fsecurity-model","5.concepts\u002F3.security-model","i-lucide-shield",{"title":199,"path":200,"stem":201,"icon":202},"FAQ","\u002Fconcepts\u002Ffaq","5.concepts\u002F4.faq","i-lucide-circle-help",{"id":204,"title":105,"body":205,"description":580,"extension":581,"links":582,"meta":583,"navigation":584,"path":106,"seo":585,"stem":107,"__hash__":586},"docs\u002F3.composables\u002F2.requirements.md",{"type":206,"value":207,"toc":571},"minimark",[208,212,217,317,320,324,389,392,408,411,415,425,432,436,466,473,477,518,528,532,535,546,550,567],[209,210,211],"p",{},"Misconfigured composition is the most common integration issue. Follow these rules when you skip the facade (or when you extend it).",[213,214,216],"h2",{"id":215},"_1-di-must-match-maps","1. DI must match maps",[218,219,220,233],"table",{},[221,222,223],"thead",{},[224,225,226,230],"tr",{},[227,228,229],"th",{},"You map…",[227,231,232],{},"You must register…",[234,235,236,252,265,277,294,307],"tbody",{},[224,237,238,245],{},[239,240,241],"td",{},[242,243,244],"code",{},"MapIdentityManagementApi",[239,246,247,248,251],{},"Identity API endpoints + EF stores + token providers (as with ",[242,249,250],{},"AddIdentityApiEndpoints"," \u002F facade)",[224,253,254,259],{},[239,255,256],{},[242,257,258],{},"MapCookieAuthEndpoints",[239,260,261,264],{},[242,262,263],{},"AddCookieAuthEndpoints()"," (+ antiforgery)",[224,266,267,272],{},[239,268,269],{},[242,270,271],{},"MapBearerAuthEndpoints",[239,273,274],{},[242,275,276],{},"AddBearerAuthEndpoints()",[224,278,279,284],{},[239,280,281],{},[242,282,283],{},"MapJwtAuthEndpoints",[239,285,286,289,290,293],{},[242,287,288],{},"AddJwtEndpoints\u003CTUser, TContext>(…)"," and ",[242,291,292],{},"UseRefreshToken()"," on the DbContext",[224,295,296,301],{},[239,297,298],{},[242,299,300],{},"MapPasskeyEndpoints",[239,302,303,306],{},[242,304,305],{},"AddPasskeyEndpoints\u003CTUser>()"," (registers default Identity completer)",[224,308,309,312],{},[239,310,311],{},"CSRF-protected routes",[239,313,314],{},[242,315,316],{},"AddAntiforgery()",[209,318,319],{},"Cookie and bearer helpers also register ReAuth schemes and rate-limit policies used by login\u002Faccount flows.",[213,321,323],{"id":322},"_2-pipeline-order","2. Pipeline order",[325,326,331],"pre",{"className":327,"code":328,"language":329,"meta":330,"style":330},"language-cs shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","app.UseAuthentication();\napp.UseAuthorization();\napp.UseRateLimiter();\napp.UseAntiforgery();\n","cs","",[242,332,333,353,365,377],{"__ignoreMap":330},[334,335,338,342,346,350],"span",{"class":336,"line":337},"line",1,[334,339,341],{"class":340},"sTEyZ","app",[334,343,345],{"class":344},"sMK4o",".",[334,347,349],{"class":348},"s2Zo4","UseAuthentication",[334,351,352],{"class":344},"();\n",[334,354,356,358,360,363],{"class":336,"line":355},2,[334,357,341],{"class":340},[334,359,345],{"class":344},[334,361,362],{"class":348},"UseAuthorization",[334,364,352],{"class":344},[334,366,368,370,372,375],{"class":336,"line":367},3,[334,369,341],{"class":340},[334,371,345],{"class":344},[334,373,374],{"class":348},"UseRateLimiter",[334,376,352],{"class":344},[334,378,380,382,384,387],{"class":336,"line":379},4,[334,381,341],{"class":340},[334,383,345],{"class":344},[334,385,386],{"class":348},"UseAntiforgery",[334,388,352],{"class":344},[209,390,391],{},"The facade equivalent is a single call:",[325,393,395],{"className":327,"code":394,"language":329,"meta":330,"style":330},"app.UseAuthEndpoints();\n",[242,396,397],{"__ignoreMap":330},[334,398,399,401,403,406],{"class":336,"line":337},[334,400,341],{"class":340},[334,402,345],{"class":344},[334,404,405],{"class":348},"UseAuthEndpoints",[334,407,352],{"class":344},[209,409,410],{},"Without rate limiting and antiforgery middleware, endpoint policies and CSRF filters will not behave correctly.",[213,412,414],{"id":413},"_3-map-management-once","3. Map management once",[209,416,417,418,420,421,345],{},"In production hosts, map ",[242,419,244],{}," ",[422,423,424],"strong",{},"once",[209,426,427,428,431],{},"If you intentionally map management on two groups (for example cookie + bearer test hosts), pass a unique ",[242,429,430],{},"confirmEmailEndpointName"," for the second map so email confirmation link generation stays unambiguous.",[213,433,435],{"id":434},"_4-antiforgery-rules","4. Antiforgery rules",[437,438,439,447,450,460],"ul",{},[440,441,442,443,446],"li",{},"Routes that change state for a cookie user use ",[242,444,445],{},"RequireAntiforgery()",", an endpoint filter.",[440,448,449],{},"The filter skips the check when a bearer scheme authenticated the request and no application or external cookie is present.",[440,451,452,453,456,457,345],{},"Clients send the ",[242,454,455],{},"RequestVerificationToken"," header. Get the token from ",[242,458,459],{},"GET …\u002FcsrfToken",[440,461,462,465],{},[242,463,464],{},"AntiforgeryEnforcementMiddleware"," is optional. The filter is enough for mapped endpoints.",[209,467,468,469,345],{},"The full route list and the failure shape are in ",[470,471,163],"a",{"href":472},"\u002Fmodules\u002Fcsrf\u002F",[213,474,476],{"id":475},"_5-rate-limit-policies","5. Rate-limit policies",[209,478,479,482,483,482,486,489,490,493,494,482,497,489,500,503,504,506,507,510,511,513,514,517],{},[242,480,481],{},"AddCookieAuthEndpoints",", ",[242,484,485],{},"AddBearerAuthEndpoints",[242,487,488],{},"AddJwtEndpoints",", and ",[242,491,492],{},"AddPasskeyEndpoints"," register the ",[242,495,496],{},"AuthEndpoints.Login",[242,498,499],{},"AuthEndpoints.AccountAbuse",[242,501,502],{},"AuthEndpoints.ConfirmIdentity"," policies. ",[242,505,492],{}," also registers the two passkey policies. ",[242,508,509],{},"AddExternalAuthEndpoints"," registers ",[242,512,496],{},". Identity bearer ",[242,515,516],{},"POST \u002Frefresh"," has no rate limit.",[209,519,520,521,524,525,345],{},"Call ",[242,522,523],{},"UseRateLimiter()"," in the pipeline. Limits and routes per policy are in ",[470,526,172],{"href":527},"\u002Fmodules\u002Frate-limits\u002F",[213,529,531],{"id":530},"_6-reauth-for-sensitive-mutations","6. ReAuth for sensitive mutations",[209,533,534],{},"Manage 2FA\u002Finfo mutations and passkey add\u002Frename\u002Fdelete\u002FcreationOptions require step-up ReAuth (plus antiforgery where applicable).",[209,536,537,538,541,542,345],{},"Hosts can protect their own endpoints with ",[242,539,540],{},".RequireReauth()"," after registering ReAuth schemes. See ",[470,543,545],{"href":544},"\u002Fmodules\u002Freauth\u002F","ReAuth",[213,547,549],{"id":548},"related","Related",[437,551,552,557,562],{},[440,553,554],{},[470,555,109],{"href":556},"\u002Fcomposables\u002Frecipes\u002F",[440,558,559],{},[470,560,18],{"href":561},"\u002Fgetting-started\u002Fquick-start\u002F",[440,563,564],{},[470,565,121],{"href":566},"\u002Fmodules\u002Fendpoints\u002F",[568,569,570],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":330,"searchDepth":337,"depth":355,"links":572},[573,574,575,576,577,578,579],{"id":215,"depth":355,"text":216},{"id":322,"depth":355,"text":323},{"id":413,"depth":355,"text":414},{"id":434,"depth":355,"text":435},{"id":475,"depth":355,"text":476},{"id":530,"depth":355,"text":531},{"id":548,"depth":355,"text":549},"Hard prerequisites for composing AuthEndpoints modules correctly.","md",null,{},{"icon":39},{"title":105,"description":580},"dHnfpqhWJAIa69BHX0__XlD2o-QoAtrQgyeNLEuXQxo",[588,590],{"title":102,"path":98,"stem":99,"description":589,"icon":103,"children":-1},"Compose Identity management, sign-in stacks, and passkeys on the prefixes your host needs.",{"title":109,"path":110,"stem":111,"description":591,"icon":112,"children":-1},"Common composition patterns for cookie web clients, Identity bearer, JWT-only, and custom paths.",1791123627697]