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