[{"data":1,"prerenderedAt":2930},["ShallowReactive",2],{"navigation":3,"\u002Fmodules\u002Fjwt":203,"\u002Fmodules\u002Fjwt-surround":2925},[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":140,"body":205,"description":2918,"extension":2919,"links":2920,"meta":2921,"navigation":2922,"path":141,"seo":2923,"stem":142,"__hash__":2924},"docs\u002F4.modules\u002F05.jwt.md",{"type":206,"value":207,"toc":2892},"minimark",[208,218,223,374,383,402,406,503,511,515,552,556,562,663,668,678,701,717,776,780,800,813,817,835,839,882,886,977,980,993,1091,1122,1135,1138,1276,1280,1485,1489,1678,1681,1884,1894,1897,2064,2068,2106,2109,2112,2126,2141,2258,2264,2316,2336,2341,2361,2637,2641,2653,2796,2800,2819,2823,2861,2865,2888],[209,210,211,212,217],"p",{},"JWT sign-in: short-lived access tokens plus an HttpOnly refresh cookie. Pair with ",[213,214,216],"a",{"href":215},"\u002Fmodules\u002Fidentity-management\u002F","Identity management"," for register\u002Fmanage.",[219,220,222],"h2",{"id":221},"di","DI",[224,225,230],"pre",{"className":226,"code":227,"language":228,"meta":229,"style":229},"language-cs shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","builder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.SymmetricKey = builder.Configuration[\"Jwt:SymmetricKey\"];\n});\n","cs","",[231,232,233,277,283,310,330,368],"code",{"__ignoreMap":229},[234,235,238,242,246,249,251,255,258,262,265,268,271,274],"span",{"class":236,"line":237},"line",1,[234,239,241],{"class":240},"sTEyZ","builder",[234,243,245],{"class":244},"sMK4o",".",[234,247,248],{"class":240},"Services",[234,250,245],{"class":244},[234,252,254],{"class":253},"s2Zo4","AddJwtEndpoints",[234,256,257],{"class":244},"\u003C",[234,259,261],{"class":260},"sBMFI","AppUser",[234,263,264],{"class":244},",",[234,266,267],{"class":260}," AppDbContext",[234,269,270],{"class":244},">(",[234,272,273],{"class":260},"o",[234,275,276],{"class":244}," =>\n",[234,278,280],{"class":236,"line":279},2,[234,281,282],{"class":244},"{\n",[234,284,286,289,291,294,297,300,304,307],{"class":236,"line":285},3,[234,287,288],{"class":240},"    o",[234,290,245],{"class":244},[234,292,293],{"class":240},"Issuer ",[234,295,296],{"class":244},"=",[234,298,299],{"class":244}," \"",[234,301,303],{"class":302},"sfazB","https:\u002F\u002Fexample.com",[234,305,306],{"class":244},"\"",[234,308,309],{"class":244},";\n",[234,311,313,315,317,320,322,324,326,328],{"class":236,"line":312},4,[234,314,288],{"class":240},[234,316,245],{"class":244},[234,318,319],{"class":240},"Audience ",[234,321,296],{"class":244},[234,323,299],{"class":244},[234,325,303],{"class":302},[234,327,306],{"class":244},[234,329,309],{"class":244},[234,331,333,335,337,340,342,345,347,350,352,355,358,360,363,365],{"class":236,"line":332},5,[234,334,288],{"class":240},[234,336,245],{"class":244},[234,338,339],{"class":240},"SigningOptions",[234,341,245],{"class":244},[234,343,344],{"class":240},"SymmetricKey ",[234,346,296],{"class":244},[234,348,349],{"class":240}," builder",[234,351,245],{"class":244},[234,353,354],{"class":240},"Configuration",[234,356,357],{"class":244},"[",[234,359,306],{"class":244},[234,361,362],{"class":302},"Jwt:SymmetricKey",[234,364,306],{"class":244},[234,366,367],{"class":244},"];\n",[234,369,371],{"class":236,"line":370},6,[234,372,373],{"class":244},"});\n",[209,375,376,378,379,382],{},[231,377,254],{}," returns a ",[231,380,381],{},"SimpleJwtBuilder"," for replacing services:",[384,385,386,392,397],"ul",{},[387,388,389],"li",{},[231,390,391],{},"AddAccessTokenGenerator\u003CT>",[387,393,394],{},[231,395,396],{},"AddRefreshTokenService\u003CT>",[387,398,399],{},[231,400,401],{},"AddErrorDescriber\u003CT>",[219,403,405],{"id":404},"ef-mapping","EF mapping",[224,407,409],{"className":226,"code":408,"language":228,"meta":229,"style":229},"using AuthEndpoints.Jwt;\n\nprotected override void OnModelCreating(ModelBuilder builder)\n{\n    base.OnModelCreating(builder);\n    builder.UseRefreshToken(); \u002F\u002F schema AuthEndpoints, table AuthEndpointsRefreshTokens\n}\n",[231,410,411,427,433,459,463,480,497],{"__ignoreMap":229},[234,412,413,417,420,422,425],{"class":236,"line":237},[234,414,416],{"class":415},"sbssI","using",[234,418,419],{"class":240}," AuthEndpoints",[234,421,245],{"class":244},[234,423,424],{"class":240},"Jwt",[234,426,309],{"class":244},[234,428,429],{"class":236,"line":279},[234,430,432],{"emptyLinePlaceholder":431},true,"\n",[234,434,435,439,442,445,448,451,454,456],{"class":236,"line":285},[234,436,438],{"class":437},"spNyl","protected",[234,440,441],{"class":437}," override",[234,443,444],{"class":244}," void",[234,446,447],{"class":253}," OnModelCreating",[234,449,450],{"class":244},"(",[234,452,453],{"class":260},"ModelBuilder",[234,455,349],{"class":260},[234,457,458],{"class":244},")\n",[234,460,461],{"class":236,"line":312},[234,462,282],{"class":244},[234,464,465,468,470,473,475,477],{"class":236,"line":332},[234,466,467],{"class":240},"    base",[234,469,245],{"class":244},[234,471,472],{"class":253},"OnModelCreating",[234,474,450],{"class":244},[234,476,241],{"class":240},[234,478,479],{"class":244},");\n",[234,481,482,485,487,490,493],{"class":236,"line":370},[234,483,484],{"class":240},"    builder",[234,486,245],{"class":244},[234,488,489],{"class":253},"UseRefreshToken",[234,491,492],{"class":244},"();",[234,494,496],{"class":495},"sHwdD"," \u002F\u002F schema AuthEndpoints, table AuthEndpointsRefreshTokens\n",[234,498,500],{"class":236,"line":499},7,[234,501,502],{"class":244},"}\n",[209,504,505,506,510],{},"Refresh tokens are stored as ",[507,508,509],"strong",{},"hashes"," only. Family reuse detection revokes the family on reuse.",[219,512,514],{"id":513},"map","Map",[224,516,518],{"className":226,"code":517,"language":228,"meta":229,"style":229},"app.MapGroup(\"\u002Fauth\").MapJwtAuthEndpoints\u003CAppUser>();\n",[231,519,520],{"__ignoreMap":229},[234,521,522,525,527,530,532,534,537,539,542,545,547,549],{"class":236,"line":237},[234,523,524],{"class":240},"app",[234,526,245],{"class":244},[234,528,529],{"class":253},"MapGroup",[234,531,450],{"class":244},[234,533,306],{"class":244},[234,535,536],{"class":302},"\u002Fauth",[234,538,306],{"class":244},[234,540,541],{"class":244},").",[234,543,544],{"class":253},"MapJwtAuthEndpoints",[234,546,257],{"class":244},[234,548,261],{"class":260},[234,550,551],{"class":244},">();\n",[219,553,555],{"id":554},"routes","Routes",[209,557,558,559,561],{},"Relative to the group prefix (facade default ",[231,560,536],{},"):",[563,564,565,581],"table",{},[566,567,568],"thead",{},[569,570,571,575,578],"tr",{},[572,573,574],"th",{},"Method",[572,576,577],{},"Path",[572,579,580],{},"Notes",[582,583,584,600,614,635,649],"tbody",{},[569,585,586,592,597],{},[587,588,589],"td",{},[231,590,591],{},"POST",[587,593,594],{},[231,595,596],{},"\u002Fcreate",[587,598,599],{},"Login; rate-limited; returns access token",[569,601,602,606,611],{},[587,603,604],{},[231,605,591],{},[587,607,608],{},[231,609,610],{},"\u002Frefresh",[587,612,613],{},"Refresh cookie + CSRF; rate-limited",[569,615,616,621,626],{},[587,617,618],{},[231,619,620],{},"GET",[587,622,623],{},[231,624,625],{},"\u002Fverify",[587,627,628,631,632],{},[231,629,630],{},"[Authorize]"," JWT Bearer → ",[231,633,634],{},"204",[569,636,637,641,646],{},[587,638,639],{},[231,640,591],{},[587,642,643],{},[231,644,645],{},"\u002Flogout",[587,647,648],{},"CSRF; revokes refresh family",[569,650,651,655,660],{},[587,652,653],{},[231,654,620],{},[587,656,657],{},[231,658,659],{},"\u002FcsrfToken",[587,661,662],{},"For refresh\u002Flogout",[664,665,667],"h3",{"id":666},"create-request-body","Create request body",[209,669,670,673,674,677],{},[231,671,672],{},"SimpleJwtLoginRequest"," on ",[231,675,676],{},"POST \u002Fcreate",":",[384,679,680,685,690,696],{},[387,681,682],{},[231,683,684],{},"email",[387,686,687],{},[231,688,689],{},"password",[387,691,692,695],{},[231,693,694],{},"twoFactorCode"," (optional)",[387,697,698,695],{},[231,699,700],{},"twoFactorRecoveryCode",[209,702,703,706,707,709,710,713,714,245],{},[231,704,705],{},"DefaultAuthenticator"," looks up ",[231,708,684],{}," as an email first, then as a user name. It checks the password with lockout on failure, and it refuses an unconfirmed account when ",[231,711,712],{},"RequireConfirmedAccount"," is ",[231,715,716],{},"true",[563,718,719,729],{},[566,720,721],{},[569,722,723,726],{},[572,724,725],{},"Result",[572,727,728],{},"Response",[582,730,731,746,762],{},[569,732,733,736],{},[587,734,735],{},"Success",[587,737,738,741,742,745],{},[231,739,740],{},"200 { \"accessToken\", \"tokenType\": \"Bearer\" }"," (",[231,743,744],{},"SimpleJwtTokenResponse",") and the refresh cookie",[569,747,748,756],{},[587,749,750,752,753,755],{},[231,751,684],{}," or ",[231,754,689],{}," missing",[587,757,758,761],{},[231,759,760],{},"400 { \"error\": \"invalid_request\", \"error_description\" }",". This body is not problem details.",[569,763,764,767],{},[587,765,766],{},"Wrong credentials, lockout, or unconfirmed account",[587,768,769,772,773],{},[231,770,771],{},"401"," problem details, detail ",[231,774,775],{},"Invalid credentials.",[664,777,779],{"id":778},"two-factor","Two-factor",[209,781,782,783,785,786,788,789,741,792,795,796,752,798,245],{},"When 2FA is enabled and neither code is provided, ",[231,784,676],{}," returns ",[507,787,771],{}," with Problem details extension ",[231,790,791],{},"requiresTwoFactor: true",[231,793,794],{},"detail",": \"Two-factor authentication is required.\"). Retry the same request with ",[231,797,694],{},[231,799,700],{},[209,801,802,803,805,806,809,810,812],{},"A wrong authenticator code returns ",[231,804,771],{}," with detail ",[231,807,808],{},"Invalid two factor code."," A wrong recovery code returns ",[231,811,771],{}," with the Identity error description. JWT sign-in never sets the Identity two-factor remember-client cookie.",[664,814,816],{"id":815},"refresh-response","Refresh response",[209,818,819,822,823,826,827,830,831,834],{},[231,820,821],{},"POST \u002Frefresh"," rotates the refresh cookie and returns ",[231,824,825],{},"200 { \"accessToken\" }",", with no ",[231,828,829],{},"tokenType",". Failures return ",[231,832,833],{},"400 { \"errors\": [\"...\"] }",". Reuse of a rotated refresh token revokes the whole token family.",[219,836,838],{"id":837},"refresh-cookie","Refresh cookie",[563,840,841,851],{},[566,842,843],{},[569,844,845,848],{},[572,846,847],{},"Property",[572,849,850],{},"Value",[582,852,853,863,874],{},[569,854,855,858],{},[587,856,857],{},"Name",[587,859,860],{},[231,861,862],{},"AuthEndpoints.Jwt.RefreshToken",[569,864,865,868],{},[587,866,867],{},"Flags",[587,869,870,871],{},"HttpOnly, SameSite=Strict, Secure when HTTPS, Path=",[231,872,873],{},"\u002F",[569,875,876,879],{},[587,877,878],{},"Default TTL",[587,880,881],{},"14 days",[219,883,885],{"id":884},"options","Options",[563,887,888,899],{},[566,889,890],{},[569,891,892,894,897],{},[572,893,847],{},[572,895,896],{},"Default",[572,898,580],{},[582,900,901,915,929,941,958],{},[569,902,903,908,912],{},[587,904,905],{},[231,906,907],{},"Issuer",[587,909,910],{},[231,911,424],{},[587,913,914],{},"Rejected in Production",[569,916,917,922,927],{},[587,918,919],{},[231,920,921],{},"Audience",[587,923,924],{},[231,925,926],{},"JwtAudience",[587,928,914],{},[569,930,931,936,939],{},[587,932,933],{},[231,934,935],{},"AccessTokenLifetime",[587,937,938],{},"15 minutes",[587,940],{},[569,942,943,947,950],{},[587,944,945],{},[231,946,339],{},[587,948,949],{},"Symmetric",[587,951,952,953,957],{},"See ",[213,954,956],{"href":955},"#signing","Signing"," for Symmetric, RSA, ECDSA, and X509",[569,959,960,965,970],{},[587,961,962],{},[231,963,964],{},"TokenValidationParameters",[587,966,967],{},[231,968,969],{},"null",[587,971,952,972,976],{},[213,973,975],{"href":974},"#advanced","Advanced"," — custom ASP.NET Core JWT Bearer validation",[219,978,956],{"id":979},"signing",[209,981,982,983,741,986,989,990,541],{},"Configure ",[231,984,985],{},"SimpleJwtOptions.SigningOptions",[231,987,988],{},"SimpleJwtSigningOptions","). Default algorithm is Symmetric (",[231,991,992],{},"HS256",[563,994,995,1012],{},[566,996,997],{},[569,998,999,1004,1007,1010],{},[572,1000,1001],{},[231,1002,1003],{},"Algorithm",[572,1005,1006],{},"Required property",[572,1008,1009],{},"Default JWT alg",[572,1011,580],{},[582,1013,1014,1033,1053,1072],{},[569,1015,1016,1021,1026,1030],{},[587,1017,1018,1020],{},[231,1019,949],{}," (default)",[587,1022,1023],{},[231,1024,1025],{},"SymmetricKey",[587,1027,1028],{},[231,1029,992],{},[587,1031,1032],{},"≥ 32 UTF-8 bytes",[569,1034,1035,1040,1045,1050],{},[587,1036,1037],{},[231,1038,1039],{},"Rsa",[587,1041,1042],{},[231,1043,1044],{},"RsaKey",[587,1046,1047],{},[231,1048,1049],{},"RS256",[587,1051,1052],{},"Or use X509 for cert-backed RSA",[569,1054,1055,1060,1065,1070],{},[587,1056,1057],{},[231,1058,1059],{},"Ecdsa",[587,1061,1062],{},[231,1063,1064],{},"EcdsaKey",[587,1066,1067],{},[231,1068,1069],{},"ES256",[587,1071],{},[569,1073,1074,1079,1084,1088],{},[587,1075,1076],{},[231,1077,1078],{},"X509",[587,1080,1081],{},[231,1082,1083],{},"Certificate",[587,1085,1086],{},[231,1087,1049],{},[587,1089,1090],{},"Certificate must include a private key",[209,1092,1093,1094,1097,1098,1101,1102,1105,1106,1109,1110,1101,1113,1101,1116,1101,1119,541],{},"Use ",[231,1095,1096],{},"AlgorithmOverride"," to pick a different JWT algorithm string (for example ",[231,1099,1100],{},"SecurityAlgorithms.RsaSha512",", ",[231,1103,1104],{},"EcdsaSha384",", or ",[231,1107,1108],{},"HmacSha512","). The options validator checks key material against the effective algorithm (",[231,1111,1112],{},"HS*",[231,1114,1115],{},"RS*",[231,1117,1118],{},"ES*",[231,1120,1121],{},"PS*",[209,1123,1124,1125,1127,1128,1131,1132,1134],{},"The same ",[231,1126,339],{}," shape works on the facade via ",[231,1129,1130],{},"o.Jwt.Configure = jwt => { … }"," or on compose via ",[231,1133,254],{}," as shown below.",[664,1136,949],{"id":1137},"symmetric",[224,1139,1141],{"className":226,"code":1140,"language":228,"meta":229,"style":229},"builder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.Symmetric; \u002F\u002F default\n    o.SigningOptions.SymmetricKey = builder.Configuration[\"Jwt:SymmetricKey\"];\n});\n",[231,1142,1143,1169,1173,1191,1209,1242,1272],{"__ignoreMap":229},[234,1144,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167],{"class":236,"line":237},[234,1146,241],{"class":240},[234,1148,245],{"class":244},[234,1150,248],{"class":240},[234,1152,245],{"class":244},[234,1154,254],{"class":253},[234,1156,257],{"class":244},[234,1158,261],{"class":260},[234,1160,264],{"class":244},[234,1162,267],{"class":260},[234,1164,270],{"class":244},[234,1166,273],{"class":260},[234,1168,276],{"class":244},[234,1170,1171],{"class":236,"line":279},[234,1172,282],{"class":244},[234,1174,1175,1177,1179,1181,1183,1185,1187,1189],{"class":236,"line":285},[234,1176,288],{"class":240},[234,1178,245],{"class":244},[234,1180,293],{"class":240},[234,1182,296],{"class":244},[234,1184,299],{"class":244},[234,1186,303],{"class":302},[234,1188,306],{"class":244},[234,1190,309],{"class":244},[234,1192,1193,1195,1197,1199,1201,1203,1205,1207],{"class":236,"line":312},[234,1194,288],{"class":240},[234,1196,245],{"class":244},[234,1198,319],{"class":240},[234,1200,296],{"class":244},[234,1202,299],{"class":244},[234,1204,303],{"class":302},[234,1206,306],{"class":244},[234,1208,309],{"class":244},[234,1210,1211,1213,1215,1217,1219,1222,1224,1227,1229,1232,1234,1236,1239],{"class":236,"line":332},[234,1212,288],{"class":240},[234,1214,245],{"class":244},[234,1216,339],{"class":240},[234,1218,245],{"class":244},[234,1220,1221],{"class":240},"Algorithm ",[234,1223,296],{"class":244},[234,1225,1226],{"class":240}," SimpleJwtSigningOptions",[234,1228,245],{"class":244},[234,1230,1231],{"class":240},"SigningAlgorithm",[234,1233,245],{"class":244},[234,1235,949],{"class":240},[234,1237,1238],{"class":244},";",[234,1240,1241],{"class":495}," \u002F\u002F default\n",[234,1243,1244,1246,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266,1268,1270],{"class":236,"line":370},[234,1245,288],{"class":240},[234,1247,245],{"class":244},[234,1249,339],{"class":240},[234,1251,245],{"class":244},[234,1253,344],{"class":240},[234,1255,296],{"class":244},[234,1257,349],{"class":240},[234,1259,245],{"class":244},[234,1261,354],{"class":240},[234,1263,357],{"class":244},[234,1265,306],{"class":244},[234,1267,362],{"class":302},[234,1269,306],{"class":244},[234,1271,367],{"class":244},[234,1273,1274],{"class":236,"line":499},[234,1275,373],{"class":244},[664,1277,1279],{"id":1278},"rsa","RSA",[224,1281,1283],{"className":226,"code":1282,"language":228,"meta":229,"style":229},"using System.Security.Cryptography;\n\nvar rsa = RSA.Create();\nrsa.ImportFromPem(File.ReadAllText(\"keys\u002Frsa-private.pem\"));\n\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.Rsa;\n    o.SigningOptions.RsaKey = rsa;\n});\n",[231,1284,1285,1304,1308,1330,1361,1365,1391,1395,1414,1433,1460,1480],{"__ignoreMap":229},[234,1286,1287,1289,1292,1294,1297,1299,1302],{"class":236,"line":237},[234,1288,416],{"class":415},[234,1290,1291],{"class":240}," System",[234,1293,245],{"class":244},[234,1295,1296],{"class":240},"Security",[234,1298,245],{"class":244},[234,1300,1301],{"class":240},"Cryptography",[234,1303,309],{"class":244},[234,1305,1306],{"class":236,"line":279},[234,1307,432],{"emptyLinePlaceholder":431},[234,1309,1310,1313,1316,1319,1322,1324,1327],{"class":236,"line":285},[234,1311,1312],{"class":260},"var",[234,1314,1315],{"class":260}," rsa",[234,1317,1318],{"class":244}," =",[234,1320,1321],{"class":240}," RSA",[234,1323,245],{"class":244},[234,1325,1326],{"class":253},"Create",[234,1328,1329],{"class":244},"();\n",[234,1331,1332,1334,1336,1339,1341,1344,1346,1349,1351,1353,1356,1358],{"class":236,"line":312},[234,1333,1278],{"class":240},[234,1335,245],{"class":244},[234,1337,1338],{"class":253},"ImportFromPem",[234,1340,450],{"class":244},[234,1342,1343],{"class":240},"File",[234,1345,245],{"class":244},[234,1347,1348],{"class":253},"ReadAllText",[234,1350,450],{"class":244},[234,1352,306],{"class":244},[234,1354,1355],{"class":302},"keys\u002Frsa-private.pem",[234,1357,306],{"class":244},[234,1359,1360],{"class":244},"));\n",[234,1362,1363],{"class":236,"line":332},[234,1364,432],{"emptyLinePlaceholder":431},[234,1366,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389],{"class":236,"line":370},[234,1368,241],{"class":240},[234,1370,245],{"class":244},[234,1372,248],{"class":240},[234,1374,245],{"class":244},[234,1376,254],{"class":253},[234,1378,257],{"class":244},[234,1380,261],{"class":260},[234,1382,264],{"class":244},[234,1384,267],{"class":260},[234,1386,270],{"class":244},[234,1388,273],{"class":260},[234,1390,276],{"class":244},[234,1392,1393],{"class":236,"line":499},[234,1394,282],{"class":244},[234,1396,1398,1400,1402,1404,1406,1408,1410,1412],{"class":236,"line":1397},8,[234,1399,288],{"class":240},[234,1401,245],{"class":244},[234,1403,293],{"class":240},[234,1405,296],{"class":244},[234,1407,299],{"class":244},[234,1409,303],{"class":302},[234,1411,306],{"class":244},[234,1413,309],{"class":244},[234,1415,1417,1419,1421,1423,1425,1427,1429,1431],{"class":236,"line":1416},9,[234,1418,288],{"class":240},[234,1420,245],{"class":244},[234,1422,319],{"class":240},[234,1424,296],{"class":244},[234,1426,299],{"class":244},[234,1428,303],{"class":302},[234,1430,306],{"class":244},[234,1432,309],{"class":244},[234,1434,1436,1438,1440,1442,1444,1446,1448,1450,1452,1454,1456,1458],{"class":236,"line":1435},10,[234,1437,288],{"class":240},[234,1439,245],{"class":244},[234,1441,339],{"class":240},[234,1443,245],{"class":244},[234,1445,1221],{"class":240},[234,1447,296],{"class":244},[234,1449,1226],{"class":240},[234,1451,245],{"class":244},[234,1453,1231],{"class":240},[234,1455,245],{"class":244},[234,1457,1039],{"class":240},[234,1459,309],{"class":244},[234,1461,1463,1465,1467,1469,1471,1474,1476,1478],{"class":236,"line":1462},11,[234,1464,288],{"class":240},[234,1466,245],{"class":244},[234,1468,339],{"class":240},[234,1470,245],{"class":244},[234,1472,1473],{"class":240},"RsaKey ",[234,1475,296],{"class":244},[234,1477,1315],{"class":240},[234,1479,309],{"class":244},[234,1481,1483],{"class":236,"line":1482},12,[234,1484,373],{"class":244},[664,1486,1488],{"id":1487},"ecdsa","ECDSA",[224,1490,1492],{"className":226,"code":1491,"language":228,"meta":229,"style":229},"using System.Security.Cryptography;\n\nvar ecdsa = ECDsa.Create();\necdsa.ImportFromPem(File.ReadAllText(\"keys\u002Fecdsa-private.pem\"));\n\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.Ecdsa;\n    o.SigningOptions.EcdsaKey = ecdsa;\n});\n",[231,1493,1494,1510,1514,1532,1559,1563,1589,1593,1611,1629,1655,1674],{"__ignoreMap":229},[234,1495,1496,1498,1500,1502,1504,1506,1508],{"class":236,"line":237},[234,1497,416],{"class":415},[234,1499,1291],{"class":240},[234,1501,245],{"class":244},[234,1503,1296],{"class":240},[234,1505,245],{"class":244},[234,1507,1301],{"class":240},[234,1509,309],{"class":244},[234,1511,1512],{"class":236,"line":279},[234,1513,432],{"emptyLinePlaceholder":431},[234,1515,1516,1518,1521,1523,1526,1528,1530],{"class":236,"line":285},[234,1517,1312],{"class":260},[234,1519,1520],{"class":260}," ecdsa",[234,1522,1318],{"class":244},[234,1524,1525],{"class":240}," ECDsa",[234,1527,245],{"class":244},[234,1529,1326],{"class":253},[234,1531,1329],{"class":244},[234,1533,1534,1536,1538,1540,1542,1544,1546,1548,1550,1552,1555,1557],{"class":236,"line":312},[234,1535,1487],{"class":240},[234,1537,245],{"class":244},[234,1539,1338],{"class":253},[234,1541,450],{"class":244},[234,1543,1343],{"class":240},[234,1545,245],{"class":244},[234,1547,1348],{"class":253},[234,1549,450],{"class":244},[234,1551,306],{"class":244},[234,1553,1554],{"class":302},"keys\u002Fecdsa-private.pem",[234,1556,306],{"class":244},[234,1558,1360],{"class":244},[234,1560,1561],{"class":236,"line":332},[234,1562,432],{"emptyLinePlaceholder":431},[234,1564,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1585,1587],{"class":236,"line":370},[234,1566,241],{"class":240},[234,1568,245],{"class":244},[234,1570,248],{"class":240},[234,1572,245],{"class":244},[234,1574,254],{"class":253},[234,1576,257],{"class":244},[234,1578,261],{"class":260},[234,1580,264],{"class":244},[234,1582,267],{"class":260},[234,1584,270],{"class":244},[234,1586,273],{"class":260},[234,1588,276],{"class":244},[234,1590,1591],{"class":236,"line":499},[234,1592,282],{"class":244},[234,1594,1595,1597,1599,1601,1603,1605,1607,1609],{"class":236,"line":1397},[234,1596,288],{"class":240},[234,1598,245],{"class":244},[234,1600,293],{"class":240},[234,1602,296],{"class":244},[234,1604,299],{"class":244},[234,1606,303],{"class":302},[234,1608,306],{"class":244},[234,1610,309],{"class":244},[234,1612,1613,1615,1617,1619,1621,1623,1625,1627],{"class":236,"line":1416},[234,1614,288],{"class":240},[234,1616,245],{"class":244},[234,1618,319],{"class":240},[234,1620,296],{"class":244},[234,1622,299],{"class":244},[234,1624,303],{"class":302},[234,1626,306],{"class":244},[234,1628,309],{"class":244},[234,1630,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649,1651,1653],{"class":236,"line":1435},[234,1632,288],{"class":240},[234,1634,245],{"class":244},[234,1636,339],{"class":240},[234,1638,245],{"class":244},[234,1640,1221],{"class":240},[234,1642,296],{"class":244},[234,1644,1226],{"class":240},[234,1646,245],{"class":244},[234,1648,1231],{"class":240},[234,1650,245],{"class":244},[234,1652,1059],{"class":240},[234,1654,309],{"class":244},[234,1656,1657,1659,1661,1663,1665,1668,1670,1672],{"class":236,"line":1462},[234,1658,288],{"class":240},[234,1660,245],{"class":244},[234,1662,339],{"class":240},[234,1664,245],{"class":244},[234,1666,1667],{"class":240},"EcdsaKey ",[234,1669,296],{"class":244},[234,1671,1520],{"class":240},[234,1673,309],{"class":244},[234,1675,1676],{"class":236,"line":1482},[234,1677,373],{"class":244},[664,1679,1078],{"id":1680},"x509",[224,1682,1684],{"className":226,"code":1683,"language":228,"meta":229,"style":229},"using System.Security.Cryptography.X509Certificates;\n\nvar certificate = X509CertificateLoader.LoadPkcs12FromFile(\n    \"certs\u002Fsigning.pfx\",\n    builder.Configuration[\"Jwt:CertificatePassword\"]);\n\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.X509;\n    o.SigningOptions.Certificate = certificate;\n});\n",[231,1685,1686,1707,1711,1731,1744,1764,1768,1794,1798,1816,1834,1860,1879],{"__ignoreMap":229},[234,1687,1688,1690,1692,1694,1696,1698,1700,1702,1705],{"class":236,"line":237},[234,1689,416],{"class":415},[234,1691,1291],{"class":240},[234,1693,245],{"class":244},[234,1695,1296],{"class":240},[234,1697,245],{"class":244},[234,1699,1301],{"class":240},[234,1701,245],{"class":244},[234,1703,1704],{"class":240},"X509Certificates",[234,1706,309],{"class":244},[234,1708,1709],{"class":236,"line":279},[234,1710,432],{"emptyLinePlaceholder":431},[234,1712,1713,1715,1718,1720,1723,1725,1728],{"class":236,"line":285},[234,1714,1312],{"class":260},[234,1716,1717],{"class":260}," certificate",[234,1719,1318],{"class":244},[234,1721,1722],{"class":240}," X509CertificateLoader",[234,1724,245],{"class":244},[234,1726,1727],{"class":253},"LoadPkcs12FromFile",[234,1729,1730],{"class":244},"(\n",[234,1732,1733,1736,1739,1741],{"class":236,"line":312},[234,1734,1735],{"class":244},"    \"",[234,1737,1738],{"class":302},"certs\u002Fsigning.pfx",[234,1740,306],{"class":244},[234,1742,1743],{"class":244},",\n",[234,1745,1746,1748,1750,1752,1754,1756,1759,1761],{"class":236,"line":332},[234,1747,484],{"class":240},[234,1749,245],{"class":244},[234,1751,354],{"class":240},[234,1753,357],{"class":244},[234,1755,306],{"class":244},[234,1757,1758],{"class":302},"Jwt:CertificatePassword",[234,1760,306],{"class":244},[234,1762,1763],{"class":244},"]);\n",[234,1765,1766],{"class":236,"line":370},[234,1767,432],{"emptyLinePlaceholder":431},[234,1769,1770,1772,1774,1776,1778,1780,1782,1784,1786,1788,1790,1792],{"class":236,"line":499},[234,1771,241],{"class":240},[234,1773,245],{"class":244},[234,1775,248],{"class":240},[234,1777,245],{"class":244},[234,1779,254],{"class":253},[234,1781,257],{"class":244},[234,1783,261],{"class":260},[234,1785,264],{"class":244},[234,1787,267],{"class":260},[234,1789,270],{"class":244},[234,1791,273],{"class":260},[234,1793,276],{"class":244},[234,1795,1796],{"class":236,"line":1397},[234,1797,282],{"class":244},[234,1799,1800,1802,1804,1806,1808,1810,1812,1814],{"class":236,"line":1416},[234,1801,288],{"class":240},[234,1803,245],{"class":244},[234,1805,293],{"class":240},[234,1807,296],{"class":244},[234,1809,299],{"class":244},[234,1811,303],{"class":302},[234,1813,306],{"class":244},[234,1815,309],{"class":244},[234,1817,1818,1820,1822,1824,1826,1828,1830,1832],{"class":236,"line":1435},[234,1819,288],{"class":240},[234,1821,245],{"class":244},[234,1823,319],{"class":240},[234,1825,296],{"class":244},[234,1827,299],{"class":244},[234,1829,303],{"class":302},[234,1831,306],{"class":244},[234,1833,309],{"class":244},[234,1835,1836,1838,1840,1842,1844,1846,1848,1850,1852,1854,1856,1858],{"class":236,"line":1462},[234,1837,288],{"class":240},[234,1839,245],{"class":244},[234,1841,339],{"class":240},[234,1843,245],{"class":244},[234,1845,1221],{"class":240},[234,1847,296],{"class":244},[234,1849,1226],{"class":240},[234,1851,245],{"class":244},[234,1853,1231],{"class":240},[234,1855,245],{"class":244},[234,1857,1078],{"class":240},[234,1859,309],{"class":244},[234,1861,1862,1864,1866,1868,1870,1873,1875,1877],{"class":236,"line":1482},[234,1863,288],{"class":240},[234,1865,245],{"class":244},[234,1867,339],{"class":240},[234,1869,245],{"class":244},[234,1871,1872],{"class":240},"Certificate ",[234,1874,296],{"class":244},[234,1876,1717],{"class":240},[234,1878,309],{"class":244},[234,1880,1882],{"class":236,"line":1881},13,[234,1883,373],{"class":244},[209,1885,1886,1887,1890,1891,541],{},"PEM with private key is also fine when you build an ",[231,1888,1889],{},"X509Certificate2"," that includes the key (for example ",[231,1892,1893],{},"X509Certificate2.CreateFromPemFile",[664,1895,1096],{"id":1896},"algorithmoverride",[224,1898,1900],{"className":226,"code":1899,"language":228,"meta":229,"style":229},"using Microsoft.IdentityModel.Tokens;\n\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.Rsa;\n    o.SigningOptions.RsaKey = rsa;\n    o.SigningOptions.AlgorithmOverride = SecurityAlgorithms.RsaSha512;\n});\n",[231,1901,1902,1921,1925,1951,1955,1973,1991,2017,2035,2060],{"__ignoreMap":229},[234,1903,1904,1906,1909,1911,1914,1916,1919],{"class":236,"line":237},[234,1905,416],{"class":415},[234,1907,1908],{"class":240}," Microsoft",[234,1910,245],{"class":244},[234,1912,1913],{"class":240},"IdentityModel",[234,1915,245],{"class":244},[234,1917,1918],{"class":240},"Tokens",[234,1920,309],{"class":244},[234,1922,1923],{"class":236,"line":279},[234,1924,432],{"emptyLinePlaceholder":431},[234,1926,1927,1929,1931,1933,1935,1937,1939,1941,1943,1945,1947,1949],{"class":236,"line":285},[234,1928,241],{"class":240},[234,1930,245],{"class":244},[234,1932,248],{"class":240},[234,1934,245],{"class":244},[234,1936,254],{"class":253},[234,1938,257],{"class":244},[234,1940,261],{"class":260},[234,1942,264],{"class":244},[234,1944,267],{"class":260},[234,1946,270],{"class":244},[234,1948,273],{"class":260},[234,1950,276],{"class":244},[234,1952,1953],{"class":236,"line":312},[234,1954,282],{"class":244},[234,1956,1957,1959,1961,1963,1965,1967,1969,1971],{"class":236,"line":332},[234,1958,288],{"class":240},[234,1960,245],{"class":244},[234,1962,293],{"class":240},[234,1964,296],{"class":244},[234,1966,299],{"class":244},[234,1968,303],{"class":302},[234,1970,306],{"class":244},[234,1972,309],{"class":244},[234,1974,1975,1977,1979,1981,1983,1985,1987,1989],{"class":236,"line":370},[234,1976,288],{"class":240},[234,1978,245],{"class":244},[234,1980,319],{"class":240},[234,1982,296],{"class":244},[234,1984,299],{"class":244},[234,1986,303],{"class":302},[234,1988,306],{"class":244},[234,1990,309],{"class":244},[234,1992,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015],{"class":236,"line":499},[234,1994,288],{"class":240},[234,1996,245],{"class":244},[234,1998,339],{"class":240},[234,2000,245],{"class":244},[234,2002,1221],{"class":240},[234,2004,296],{"class":244},[234,2006,1226],{"class":240},[234,2008,245],{"class":244},[234,2010,1231],{"class":240},[234,2012,245],{"class":244},[234,2014,1039],{"class":240},[234,2016,309],{"class":244},[234,2018,2019,2021,2023,2025,2027,2029,2031,2033],{"class":236,"line":1397},[234,2020,288],{"class":240},[234,2022,245],{"class":244},[234,2024,339],{"class":240},[234,2026,245],{"class":244},[234,2028,1473],{"class":240},[234,2030,296],{"class":244},[234,2032,1315],{"class":240},[234,2034,309],{"class":244},[234,2036,2037,2039,2041,2043,2045,2048,2050,2053,2055,2058],{"class":236,"line":1416},[234,2038,288],{"class":240},[234,2040,245],{"class":244},[234,2042,339],{"class":240},[234,2044,245],{"class":244},[234,2046,2047],{"class":240},"AlgorithmOverride ",[234,2049,296],{"class":244},[234,2051,2052],{"class":240}," SecurityAlgorithms",[234,2054,245],{"class":244},[234,2056,2057],{"class":240},"RsaSha512",[234,2059,309],{"class":244},[234,2061,2062],{"class":236,"line":1435},[234,2063,373],{"class":244},[664,2065,2067],{"id":2066},"validation-notes","Validation notes",[384,2069,2070,2079,2088,2094,2100],{},[387,2071,2072,2073,2075,2076,2078],{},"Symmetric \u002F ",[231,2074,1112],{},": ",[231,2077,1025],{}," is required and must be at least 256 bits (32 UTF-8 bytes)",[387,2080,2081,2075,2083,752,2085,2087],{},[231,2082,1115],{},[231,2084,1044],{},[231,2086,1083],{}," is required",[387,2089,2090,2075,2092,2087],{},[231,2091,1118],{},[231,2093,1064],{},[387,2095,2096,2075,2098,2087],{},[231,2097,1121],{},[231,2099,1044],{},[387,2101,2102,2103,245],{},"Production still rejects the default issuer and audience. See ",[213,2104,91],{"href":2105},"\u002Fguides\u002Fproduction\u002F",[219,2107,975],{"id":2108},"advanced",[664,2110,964],{"id":2111},"tokenvalidationparameters",[209,2113,2114,2115,2118,2119,2121,2122,2125],{},"Access-token ",[507,2116,2117],{},"validation"," always goes through ASP.NET Core JWT Bearer and ",[231,2120,964],{},". Changing the signing algorithm does not bypass that path — it only changes which ",[231,2123,2124],{},"SecurityKey"," is used.",[209,2127,2128,2129,713,2132,2134,2135,2137,2138,677],{},"When ",[231,2130,2131],{},"SimpleJwtOptions.TokenValidationParameters",[231,2133,969],{}," (the default), ",[231,2136,254],{}," builds parameters like this and assigns them to ",[231,2139,2140],{},"JwtBearerOptions.TokenValidationParameters",[224,2142,2144],{"className":226,"code":2143,"language":228,"meta":229,"style":229},"new TokenValidationParameters\n{\n    ValidateIssuer = true,\n    ValidIssuer = options.Issuer,\n    ValidateAudience = true,\n    ValidAudience = options.Audience,\n    ValidateLifetime = true,\n    ValidateIssuerSigningKey = true,\n    IssuerSigningKey = options.SigningOptions.ToSecurityKey()\n}\n",[231,2145,2146,2154,2158,2171,2186,2197,2211,2222,2233,2254],{"__ignoreMap":229},[234,2147,2148,2151],{"class":236,"line":237},[234,2149,2150],{"class":437},"new",[234,2152,2153],{"class":240}," TokenValidationParameters\n",[234,2155,2156],{"class":236,"line":279},[234,2157,282],{"class":244},[234,2159,2160,2163,2165,2169],{"class":236,"line":285},[234,2161,2162],{"class":240},"    ValidateIssuer ",[234,2164,296],{"class":244},[234,2166,2168],{"class":2167},"sfNiH"," true",[234,2170,1743],{"class":240},[234,2172,2173,2176,2178,2181,2183],{"class":236,"line":312},[234,2174,2175],{"class":240},"    ValidIssuer ",[234,2177,296],{"class":244},[234,2179,2180],{"class":240}," options",[234,2182,245],{"class":244},[234,2184,2185],{"class":240},"Issuer,\n",[234,2187,2188,2191,2193,2195],{"class":236,"line":332},[234,2189,2190],{"class":240},"    ValidateAudience ",[234,2192,296],{"class":244},[234,2194,2168],{"class":2167},[234,2196,1743],{"class":240},[234,2198,2199,2202,2204,2206,2208],{"class":236,"line":370},[234,2200,2201],{"class":240},"    ValidAudience ",[234,2203,296],{"class":244},[234,2205,2180],{"class":240},[234,2207,245],{"class":244},[234,2209,2210],{"class":240},"Audience,\n",[234,2212,2213,2216,2218,2220],{"class":236,"line":499},[234,2214,2215],{"class":240},"    ValidateLifetime ",[234,2217,296],{"class":244},[234,2219,2168],{"class":2167},[234,2221,1743],{"class":240},[234,2223,2224,2227,2229,2231],{"class":236,"line":1397},[234,2225,2226],{"class":240},"    ValidateIssuerSigningKey ",[234,2228,296],{"class":244},[234,2230,2168],{"class":2167},[234,2232,1743],{"class":240},[234,2234,2235,2238,2240,2242,2244,2246,2248,2251],{"class":236,"line":1416},[234,2236,2237],{"class":240},"    IssuerSigningKey ",[234,2239,296],{"class":244},[234,2241,2180],{"class":240},[234,2243,245],{"class":244},[234,2245,339],{"class":240},[234,2247,245],{"class":244},[234,2249,2250],{"class":253},"ToSecurityKey",[234,2252,2253],{"class":244},"()\n",[234,2255,2256],{"class":236,"line":1435},[234,2257,502],{"class":244},[209,2259,2260,2263],{},[231,2261,2262],{},"ToSecurityKey()"," returns the key type for the configured algorithm:",[563,2265,2266,2278],{},[566,2267,2268],{},[569,2269,2270,2272],{},[572,2271,1003],{},[572,2273,2274,2277],{},[231,2275,2276],{},"IssuerSigningKey"," type",[582,2279,2280,2289,2298,2307],{},[569,2281,2282,2284],{},[587,2283,949],{},[587,2285,2286],{},[231,2287,2288],{},"SymmetricSecurityKey",[569,2290,2291,2293],{},[587,2292,1039],{},[587,2294,2295],{},[231,2296,2297],{},"RsaSecurityKey",[569,2299,2300,2302],{},[587,2301,1059],{},[587,2303,2304],{},[231,2305,2306],{},"ECDsaSecurityKey",[569,2308,2309,2311],{},[587,2310,1078],{},[587,2312,2313],{},[231,2314,2315],{},"X509SecurityKey",[209,2317,2318,2319,2322,2323,741,2326,2328,2329,2328,2331,2333,2334,245],{},"Signing (token ",[507,2320,2321],{},"creation",") uses ",[231,2324,2325],{},"SigningOptions.ToSigningCredentials()",[231,2327,992],{}," \u002F ",[231,2330,1049],{},[231,2332,1069],{}," \u002F etc.). Validation checks the JWT signature against ",[231,2335,2276],{},[2337,2338,2340],"h4",{"id":2339},"custom-tokenvalidationparameters","Custom TokenValidationParameters",[209,2342,2343,2344,2346,2347,2350,2351,2354,2355,2357,2358,2360],{},"If you set ",[231,2345,964],{}," yourself, that object is used ",[507,2348,2349],{},"as-is",". AuthEndpoints does ",[507,2352,2353],{},"not"," merge ",[231,2356,339],{}," into it — you must set ",[231,2359,2276],{}," (and issuer\u002Faudience rules) on your override:",[224,2362,2364],{"className":226,"code":2363,"language":228,"meta":229,"style":229},"using Microsoft.IdentityModel.Tokens;\n\nbuilder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(o =>\n{\n    o.Issuer = \"https:\u002F\u002Fexample.com\";\n    o.Audience = \"https:\u002F\u002Fexample.com\";\n    o.SigningOptions.Algorithm = SimpleJwtSigningOptions.SigningAlgorithm.Rsa;\n    o.SigningOptions.RsaKey = rsa;\n\n    \u002F\u002F Used for token creation (SigningOptions) AND you must wire validation yourself:\n    o.TokenValidationParameters = new TokenValidationParameters\n    {\n        ValidateIssuer = true,\n        ValidIssuer = \"https:\u002F\u002Fexample.com\",\n        ValidateAudience = true,\n        ValidAudience = \"https:\u002F\u002Fexample.com\",\n        ValidateLifetime = true,\n        ValidateIssuerSigningKey = true,\n        IssuerSigningKey = o.SigningOptions.ToSecurityKey()\n    };\n});\n",[231,2365,2366,2382,2386,2412,2416,2434,2452,2478,2496,2500,2505,2521,2526,2537,2553,2565,2581,2593,2605,2626,2632],{"__ignoreMap":229},[234,2367,2368,2370,2372,2374,2376,2378,2380],{"class":236,"line":237},[234,2369,416],{"class":415},[234,2371,1908],{"class":240},[234,2373,245],{"class":244},[234,2375,1913],{"class":240},[234,2377,245],{"class":244},[234,2379,1918],{"class":240},[234,2381,309],{"class":244},[234,2383,2384],{"class":236,"line":279},[234,2385,432],{"emptyLinePlaceholder":431},[234,2387,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410],{"class":236,"line":285},[234,2389,241],{"class":240},[234,2391,245],{"class":244},[234,2393,248],{"class":240},[234,2395,245],{"class":244},[234,2397,254],{"class":253},[234,2399,257],{"class":244},[234,2401,261],{"class":260},[234,2403,264],{"class":244},[234,2405,267],{"class":260},[234,2407,270],{"class":244},[234,2409,273],{"class":260},[234,2411,276],{"class":244},[234,2413,2414],{"class":236,"line":312},[234,2415,282],{"class":244},[234,2417,2418,2420,2422,2424,2426,2428,2430,2432],{"class":236,"line":332},[234,2419,288],{"class":240},[234,2421,245],{"class":244},[234,2423,293],{"class":240},[234,2425,296],{"class":244},[234,2427,299],{"class":244},[234,2429,303],{"class":302},[234,2431,306],{"class":244},[234,2433,309],{"class":244},[234,2435,2436,2438,2440,2442,2444,2446,2448,2450],{"class":236,"line":370},[234,2437,288],{"class":240},[234,2439,245],{"class":244},[234,2441,319],{"class":240},[234,2443,296],{"class":244},[234,2445,299],{"class":244},[234,2447,303],{"class":302},[234,2449,306],{"class":244},[234,2451,309],{"class":244},[234,2453,2454,2456,2458,2460,2462,2464,2466,2468,2470,2472,2474,2476],{"class":236,"line":499},[234,2455,288],{"class":240},[234,2457,245],{"class":244},[234,2459,339],{"class":240},[234,2461,245],{"class":244},[234,2463,1221],{"class":240},[234,2465,296],{"class":244},[234,2467,1226],{"class":240},[234,2469,245],{"class":244},[234,2471,1231],{"class":240},[234,2473,245],{"class":244},[234,2475,1039],{"class":240},[234,2477,309],{"class":244},[234,2479,2480,2482,2484,2486,2488,2490,2492,2494],{"class":236,"line":1397},[234,2481,288],{"class":240},[234,2483,245],{"class":244},[234,2485,339],{"class":240},[234,2487,245],{"class":244},[234,2489,1473],{"class":240},[234,2491,296],{"class":244},[234,2493,1315],{"class":240},[234,2495,309],{"class":244},[234,2497,2498],{"class":236,"line":1416},[234,2499,432],{"emptyLinePlaceholder":431},[234,2501,2502],{"class":236,"line":1435},[234,2503,2504],{"class":495},"    \u002F\u002F Used for token creation (SigningOptions) AND you must wire validation yourself:\n",[234,2506,2507,2509,2511,2514,2516,2519],{"class":236,"line":1462},[234,2508,288],{"class":240},[234,2510,245],{"class":244},[234,2512,2513],{"class":240},"TokenValidationParameters ",[234,2515,296],{"class":244},[234,2517,2518],{"class":244}," new",[234,2520,2153],{"class":260},[234,2522,2523],{"class":236,"line":1482},[234,2524,2525],{"class":244},"    {\n",[234,2527,2528,2531,2533,2535],{"class":236,"line":1881},[234,2529,2530],{"class":240},"        ValidateIssuer ",[234,2532,296],{"class":244},[234,2534,2168],{"class":2167},[234,2536,1743],{"class":244},[234,2538,2540,2543,2545,2547,2549,2551],{"class":236,"line":2539},14,[234,2541,2542],{"class":240},"        ValidIssuer ",[234,2544,296],{"class":244},[234,2546,299],{"class":244},[234,2548,303],{"class":302},[234,2550,306],{"class":244},[234,2552,1743],{"class":244},[234,2554,2556,2559,2561,2563],{"class":236,"line":2555},15,[234,2557,2558],{"class":240},"        ValidateAudience ",[234,2560,296],{"class":244},[234,2562,2168],{"class":2167},[234,2564,1743],{"class":244},[234,2566,2568,2571,2573,2575,2577,2579],{"class":236,"line":2567},16,[234,2569,2570],{"class":240},"        ValidAudience ",[234,2572,296],{"class":244},[234,2574,299],{"class":244},[234,2576,303],{"class":302},[234,2578,306],{"class":244},[234,2580,1743],{"class":244},[234,2582,2584,2587,2589,2591],{"class":236,"line":2583},17,[234,2585,2586],{"class":240},"        ValidateLifetime ",[234,2588,296],{"class":244},[234,2590,2168],{"class":2167},[234,2592,1743],{"class":244},[234,2594,2596,2599,2601,2603],{"class":236,"line":2595},18,[234,2597,2598],{"class":240},"        ValidateIssuerSigningKey ",[234,2600,296],{"class":244},[234,2602,2168],{"class":2167},[234,2604,1743],{"class":244},[234,2606,2608,2611,2613,2616,2618,2620,2622,2624],{"class":236,"line":2607},19,[234,2609,2610],{"class":240},"        IssuerSigningKey ",[234,2612,296],{"class":244},[234,2614,2615],{"class":240}," o",[234,2617,245],{"class":244},[234,2619,339],{"class":240},[234,2621,245],{"class":244},[234,2623,2250],{"class":253},[234,2625,2253],{"class":244},[234,2627,2629],{"class":236,"line":2628},20,[234,2630,2631],{"class":244},"    };\n",[234,2633,2635],{"class":236,"line":2634},21,[234,2636,373],{"class":244},[2337,2638,2640],{"id":2639},"jwtbeareroptions-callback","JwtBearerOptions callback",[209,2642,2643,2645,2646,2649,2650,2652],{},[231,2644,254],{}," also accepts an optional ",[231,2647,2648],{},"Action\u003CJwtBearerOptions>"," to tweak the bearer handler after ",[231,2651,964],{}," are assigned (events, metadata address, etc.):",[224,2654,2656],{"className":226,"code":2655,"language":228,"meta":229,"style":229},"builder.Services.AddJwtEndpoints\u003CAppUser, AppDbContext>(\n    o =>\n    {\n        o.Issuer = \"https:\u002F\u002Fexample.com\";\n        o.Audience = \"https:\u002F\u002Fexample.com\";\n        o.SigningOptions.SymmetricKey = builder.Configuration[\"Jwt:SymmetricKey\"];\n    },\n    jwt =>\n    {\n        jwt.MapInboundClaims = false;\n    });\n",[231,2657,2658,2681,2687,2691,2710,2728,2758,2763,2770,2774,2791],{"__ignoreMap":229},[234,2659,2660,2662,2664,2666,2668,2670,2672,2674,2676,2678],{"class":236,"line":237},[234,2661,241],{"class":240},[234,2663,245],{"class":244},[234,2665,248],{"class":240},[234,2667,245],{"class":244},[234,2669,254],{"class":253},[234,2671,257],{"class":244},[234,2673,261],{"class":260},[234,2675,264],{"class":244},[234,2677,267],{"class":260},[234,2679,2680],{"class":244},">(\n",[234,2682,2683,2685],{"class":236,"line":279},[234,2684,288],{"class":260},[234,2686,276],{"class":244},[234,2688,2689],{"class":236,"line":285},[234,2690,2525],{"class":244},[234,2692,2693,2696,2698,2700,2702,2704,2706,2708],{"class":236,"line":312},[234,2694,2695],{"class":240},"        o",[234,2697,245],{"class":244},[234,2699,293],{"class":240},[234,2701,296],{"class":244},[234,2703,299],{"class":244},[234,2705,303],{"class":302},[234,2707,306],{"class":244},[234,2709,309],{"class":244},[234,2711,2712,2714,2716,2718,2720,2722,2724,2726],{"class":236,"line":332},[234,2713,2695],{"class":240},[234,2715,245],{"class":244},[234,2717,319],{"class":240},[234,2719,296],{"class":244},[234,2721,299],{"class":244},[234,2723,303],{"class":302},[234,2725,306],{"class":244},[234,2727,309],{"class":244},[234,2729,2730,2732,2734,2736,2738,2740,2742,2744,2746,2748,2750,2752,2754,2756],{"class":236,"line":370},[234,2731,2695],{"class":240},[234,2733,245],{"class":244},[234,2735,339],{"class":240},[234,2737,245],{"class":244},[234,2739,344],{"class":240},[234,2741,296],{"class":244},[234,2743,349],{"class":240},[234,2745,245],{"class":244},[234,2747,354],{"class":240},[234,2749,357],{"class":244},[234,2751,306],{"class":244},[234,2753,362],{"class":302},[234,2755,306],{"class":244},[234,2757,367],{"class":244},[234,2759,2760],{"class":236,"line":499},[234,2761,2762],{"class":244},"    },\n",[234,2764,2765,2768],{"class":236,"line":1397},[234,2766,2767],{"class":260},"    jwt",[234,2769,276],{"class":244},[234,2771,2772],{"class":236,"line":1416},[234,2773,2525],{"class":244},[234,2775,2776,2779,2781,2784,2786,2789],{"class":236,"line":1435},[234,2777,2778],{"class":240},"        jwt",[234,2780,245],{"class":244},[234,2782,2783],{"class":240},"MapInboundClaims ",[234,2785,296],{"class":244},[234,2787,2788],{"class":2167}," false",[234,2790,309],{"class":244},[234,2792,2793],{"class":236,"line":1462},[234,2794,2795],{"class":244},"    });\n",[219,2797,2799],{"id":2798},"client-notes","Client notes",[2801,2802,2803,2809],"ol",{},[387,2804,2805,2806,245],{},"Store\u002Fsend access token as ",[231,2807,2808],{},"Authorization: Bearer …",[387,2810,2811,2812,2815,2816,245],{},"Refresh\u002Flogout need credentials (cookie) + ",[231,2813,2814],{},"RequestVerificationToken"," from ",[231,2817,2818],{},"GET \u002Fauth\u002FcsrfToken",[219,2820,2822],{"id":2821},"gotchas","Gotchas",[384,2824,2825,2844,2851],{},[387,2826,2827,2828,2831,2832,2835,2836,2840,2841,2843],{},"Passkey register\u002Flogin do not mint Simple JWT by default. Register ",[231,2829,2830],{},"JwtPasskeySignInCompleter"," via ",[231,2833,2834],{},"AddPasskeySignInCompleter"," (see ",[213,2837,2839],{"href":2838},"\u002Fmodules\u002Fpasskeys\u002F#simple-jwt","Passkeys","). Do not send users through password ",[231,2842,596],{}," after a successful passkey.",[387,2845,2846,2847,2850],{},"Migrate after ",[231,2848,2849],{},"UseRefreshToken()","; recreate the table when upgrading from plaintext storage.",[387,2852,2853,2854,2857,2858,245],{},"Call ",[231,2855,2856],{},"UseRateLimiter()"," and ",[231,2859,2860],{},"UseAntiforgery()",[219,2862,2864],{"id":2863},"related","Related",[384,2866,2867,2872,2878,2882],{},[387,2868,2869],{},[213,2870,2839],{"href":2871},"\u002Fmodules\u002Fpasskeys\u002F",[387,2873,2874],{},[213,2875,2877],{"href":2876},"\u002Fmodules\u002Fconfiguration\u002F#jwt","Facade JWT opt-in",[387,2879,2880],{},[213,2881,91],{"href":2105},[387,2883,2884],{},[213,2885,2887],{"href":2886},"\u002Fguides\u002Fsign-in\u002F#sign-in-with-a-password-and-a-jwt","Sign in with a password and a JWT",[2889,2890,2891],"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 pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":229,"searchDepth":237,"depth":279,"links":2893},[2894,2895,2896,2897,2902,2903,2904,2912,2915,2916,2917],{"id":221,"depth":279,"text":222},{"id":404,"depth":279,"text":405},{"id":513,"depth":279,"text":514},{"id":554,"depth":279,"text":555,"children":2898},[2899,2900,2901],{"id":666,"depth":285,"text":667},{"id":778,"depth":285,"text":779},{"id":815,"depth":285,"text":816},{"id":837,"depth":279,"text":838},{"id":884,"depth":279,"text":885},{"id":979,"depth":279,"text":956,"children":2905},[2906,2907,2908,2909,2910,2911],{"id":1137,"depth":285,"text":949},{"id":1278,"depth":285,"text":1279},{"id":1487,"depth":285,"text":1488},{"id":1680,"depth":285,"text":1078},{"id":1896,"depth":285,"text":1096},{"id":2066,"depth":285,"text":2067},{"id":2108,"depth":279,"text":975,"children":2913},[2914],{"id":2111,"depth":285,"text":964},{"id":2798,"depth":279,"text":2799},{"id":2821,"depth":279,"text":2822},{"id":2863,"depth":279,"text":2864},"JWT access tokens with an HttpOnly refresh cookie, hashed storage, and reuse detection.","md",null,{},{"icon":143},{"title":140,"description":2918},"GPCiFu_7OlT8QAcix2-Rfpl7_2EC2WpGKmASJQ1SUPw",[2926,2928],{"title":135,"path":136,"stem":137,"description":2927,"icon":138,"children":-1},"Identity bearer token login, refresh, and logout endpoints.",{"title":145,"path":146,"stem":147,"description":2929,"icon":74,"children":-1},"WebAuthn passwordless register\u002Flogin and credential management endpoints.",1791123628160]