├── .config
└── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .paket
└── Paket.Restore.targets
├── .vscode
└── settings.json
├── CodeMaid.config
├── Directory.Build.props
├── LICENSE
├── README.md
├── global.json
├── omnisharp.json
├── paket.dependencies
├── paket.lock
├── scripts
└── build.ps1
├── src
├── SuperTokens.AspNetCore
│ ├── AccessToken.cs
│ ├── AccessTokenSigningKey.cs
│ ├── AccessTokenUtilities.cs
│ ├── ApiVersionContainer.cs
│ ├── DependencyInjection
│ │ └── SuperTokensExtensions.cs
│ ├── Events
│ │ ├── MessageReceivedContext.cs
│ │ └── SuperTokensEvents.cs
│ ├── Handshake.cs
│ ├── HandshakeContainer.cs
│ ├── IApiVersionContainer.cs
│ ├── IHandshakeContainer.cs
│ ├── ISessionAccessor.cs
│ ├── ISessionRecipe.cs
│ ├── JwtUtilities.cs
│ ├── SessionAccessor.cs
│ ├── SessionRecipe.cs
│ ├── SuperTokens.AspNetCore.csproj
│ ├── SuperTokensAntiCsrfMode.cs
│ ├── SuperTokensDefaults.cs
│ ├── SuperTokensHandler.cs
│ ├── SuperTokensOptions.cs
│ ├── SuperTokensPostConfigureOptions.cs
│ ├── SuperTokensSession.cs
│ ├── TaskUtilities.cs
│ └── paket.references
└── SuperTokens.Net
│ ├── Core
│ ├── ApiVersionResponse.cs
│ ├── CookieInfo.cs
│ ├── Session.cs
│ ├── ThirdPartyUser.cs
│ └── User.cs
│ ├── CoreApiClient.cs
│ ├── CoreApiResponseException.cs
│ ├── ICoreApiClient.cs
│ ├── SessionRecipe
│ ├── CreateSessionRequest.cs
│ ├── CreateSessionResponse.cs
│ ├── DeleteSessionRequest.cs
│ ├── DeleteSessionResponse.cs
│ ├── Handshake.cs
│ ├── KeyInfo.cs
│ ├── RefreshSessionRequest.cs
│ ├── RefreshSessionResponse.cs
│ ├── RegenerateSessionRequest.cs
│ ├── RegenerateSessionResponse.cs
│ ├── SessionHandlesResponse.cs
│ ├── SessionResponse.cs
│ ├── VerifySessionRequest.cs
│ └── VerifySessionResponse.cs
│ └── SuperTokens.Net.csproj
├── supertokens-dotnet.sln
└── test
├── SuperTokens.AspNetCore.Tests
├── IntegrationTests.cs
├── LoginController.cs
├── Startup.cs
├── SuperTokens.AspNetCore.Tests.csproj
├── ValuesController.cs
└── paket.references
├── SuperTokens.Net.Tests
├── FunctionalTests.cs
├── SuperTokens.Net.Tests.csproj
└── paket.references
└── SuperTokens.TestServer
├── Controllers
└── SuperTokensController.cs
├── Counters.cs
├── CountersMiddleware.cs
├── Models
├── LoginRequest.cs
└── SetAntiCsrfRequest.cs
├── Program.cs
├── Properties
└── launchSettings.json
├── Startup.cs
├── SuperTokens.TestServer.csproj
├── UpdateableSuperTokensOptions.cs
├── appsettings.Development.json
├── appsettings.json
└── wwwroot
└── index.html
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "dotnet-format": {
6 | "version": "5.1.225507",
7 | "commands": [
8 | "dotnet-format"
9 | ]
10 | },
11 | "paket": {
12 | "version": "6.1.2",
13 | "commands": [
14 | "paket"
15 | ]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_size = 4
6 | indent_style = space
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | ##### .NET Framework/.NET Core Projects #####
11 |
12 | [*.sln]
13 | charset = utf-8-bom
14 | indent_style = tab
15 |
16 | [*.{csproj,dcproj,vbproj}]
17 | charset = utf-8-bom
18 | indent_size = 2
19 |
20 | [*.{cs,csx,vb,vbx}]
21 | charset = utf-8-bom
22 | max_line_length = 120
23 |
24 | dotnet_style_qualification_for_field = false:warning
25 | dotnet_style_qualification_for_property = true:warning
26 | dotnet_style_qualification_for_method = true:warning
27 | dotnet_style_qualification_for_event = true:warning
28 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
29 | dotnet_style_predefined_type_for_member_access = true:suggestion
30 | dotnet_style_require_accessibility_modifiers = always:warning
31 | dotnet_style_readonly_field = true:warning
32 | dotnet_style_object_initializer = true:suggestion
33 | dotnet_style_collection_initializer = true:suggestion
34 | dotnet_style_explicit_tuple_names = true:suggestion
35 | dotnet_style_prefer_inferred_tuple_names = true:suggestion
36 | dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
37 | dotnet_style_prefer_auto_properties = true:suggestion
38 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
39 | dotnet_style_coalesce_expression = true:suggestion
40 | dotnet_style_null_propagation = true:suggestion
41 |
42 | csharp_style_var_for_built_in_types = true:suggestion
43 | csharp_style_var_when_type_is_apparent = true:suggestion
44 | csharp_style_var_elsewhere = true:suggestion
45 | csharp_style_expression_bodied_methods = true:suggestion
46 | csharp_style_expression_bodied_constructors = true:suggestion
47 | csharp_style_expression_bodied_operators = true:suggestion
48 | csharp_style_expression_bodied_properties = true:suggestion
49 | csharp_style_expression_bodied_indexers = true:suggestion
50 | csharp_style_expression_bodied_accessors = true:suggestion
51 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
52 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
53 | csharp_style_inlined_variable_declaration = true:suggestion
54 | csharp_style_deconstructed_variable_declaration = true:suggestion
55 | csharp_style_pattern_local_over_anonymous_function = true:suggestion
56 | csharp_style_throw_expression = true:suggestion
57 | csharp_style_conditional_delegate_call = true:suggestion
58 |
59 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
60 | csharp_prefer_simple_default_expression = true:suggestion
61 | csharp_prefer_braces = true:suggestion
62 |
63 | visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
64 |
65 | dotnet_sort_system_directives_first = true
66 |
67 | csharp_new_line_before_open_brace = all
68 | csharp_new_line_before_else = true
69 | csharp_new_line_before_catch = true
70 | csharp_new_line_before_finally = true
71 | csharp_new_line_before_members_in_object_initializers = true
72 | csharp_new_line_before_members_in_anonymous_types = true
73 | csharp_new_line_between_query_expression_clauses = true
74 |
75 | csharp_indent_case_contents = true
76 | csharp_indent_switch_labels = true
77 | csharp_indent_labels = flush_left
78 |
79 | csharp_space_after_cast = false
80 | csharp_space_after_keywords_in_control_flow_statements = true
81 | csharp_space_between_method_declaration_parameter_list_parentheses = false
82 | csharp_space_between_method_call_parameter_list_parentheses = false
83 | csharp_space_between_parentheses = false
84 | csharp_space_before_colon_in_inheritance_clause = true
85 | csharp_space_after_colon_in_inheritance_clause = true
86 | csharp_space_around_binary_operators = before_and_after
87 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
88 | csharp_space_between_method_call_name_and_opening_parenthesis = false
89 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
90 |
91 | csharp_preserve_single_line_statements = false
92 | csharp_preserve_single_line_blocks = true
93 |
94 | [*.cs]
95 | dotnet_diagnostic.CA1031.severity = suggestion
96 | dotnet_diagnostic.CA1054.severity = suggestion
97 | dotnet_diagnostic.CA1055.severity = suggestion
98 | dotnet_diagnostic.CA1056.severity = suggestion
99 | dotnet_diagnostic.CA1303.severity = none
100 | dotnet_diagnostic.CA2007.severity = none
101 | dotnet_diagnostic.S112.severity = suggestion
102 |
103 | [paket.references]
104 | insert_final_newline = false
105 |
106 | ##### Documents #####
107 |
108 | [*.code-workspace]
109 | indent_size = 2
110 |
111 | [*.{css,less,sass,scss,styl}]
112 | indent_size = 2
113 | max_line_length = 120
114 |
115 | [*.{html,htm,xhtml}]
116 | indent_size = 2
117 | max_line_length = 120
118 |
119 | [*.{js,jsx,ts,tsx}]
120 | indent_size = 2
121 | max_line_length = 120
122 |
123 | [*.json]
124 | indent_size = 2
125 | max_line_length = 120
126 |
127 | [*.md]
128 | indent_size = 2
129 |
130 | [*.svg]
131 | indent_size = 2
132 | max_line_length = 120
133 |
134 | [*.{xml,xslt}]
135 | indent_size = 2
136 | max_line_length = 120
137 |
138 | [*.{yml,yaml}]
139 | indent_size = 2
140 | max_line_length = 120
141 |
142 | [.nvmrc]
143 | insert_final_newline = false
144 |
145 | ##### Shell Scripts #####
146 |
147 | [*.{bat,cmd}]
148 | end_of_line = crlf
149 | indent_size = 2
150 | max_line_length = 120
151 |
152 | [*.ps1]
153 | end_of_line = lf
154 | max_line_length = 120
155 |
156 | [*.sh]
157 | end_of_line = lf
158 | indent_size = 2
159 | max_line_length = 120
160 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 | *.7z binary
3 | *.ada text diff=ada
4 | *.ai binary
5 | *.bat text eol=crlf
6 | *.bib text diff=bibtex
7 | *.bmp binary
8 | *.c text diff=cpp
9 | *.class binary
10 | *.cmd text eol=crlf
11 | *.code-workspace text
12 | *.cpp text diff=cpp
13 | *.cs text diff=csharp
14 | *.csproj text
15 | *.css text diff=css
16 | *.csv text
17 | *.dcproj text
18 | *.dll binary
19 | *.doc binary diff=astextplain
20 | *.Dockerfile text
21 | *.docm binary diff=astextplain
22 | *.docx binary diff=astextplain
23 | *.dot binary diff=astextplain
24 | *.dotm binary diff=astextplain
25 | *.dotx binary diff=astextplain
26 | *.env text
27 | *.eot binary
28 | *.eps binary
29 | *.exe binary
30 | *.f text diff=fortran
31 | *.f90 text diff=fortran
32 | *.for text diff=fortran
33 | *.gif binary
34 | *.go text diff=golang
35 | *.gz binary
36 | *.h text diff=cpp
37 | *.htm text diff=html
38 | *.html text diff=html
39 | *.ico binary
40 | *.ini text
41 | *.jar binary
42 | *.java text diff=java
43 | *.jpeg binary
44 | *.jpg binary
45 | *.js text
46 | *.json text
47 | *.jsp text
48 | *.jsx text
49 | *.less text
50 | *.m text diff=matlab
51 | *.m4a binary
52 | *.m4v binary
53 | *.md text
54 | *.mid binary
55 | *.midi binary
56 | *.mov binary
57 | *.mp3 binary
58 | *.mp4 binary
59 | *.mpeg binary
60 | *.mpg binary
61 | *.o binary
62 | *.odf binary diff=astextplain
63 | *.odp binary
64 | *.ods binary diff=astextplain
65 | *.odt binary diff=astextplain
66 | *.ogg binary
67 | *.otf binary
68 | *.pas text diff=pascal
69 | *.pbxproj binary
70 | *.pdb binary
71 | *.pdf binary diff=astextplain
72 | *.php text diff=php
73 | *.pl text diff=perl
74 | *.pm text diff=perl
75 | *.png binary
76 | *.pot binary
77 | *.potx binary
78 | *.pp text diff=pascal
79 | *.ppt binary
80 | *.pptx binary
81 | *.properties text
82 | *.props text
83 | *.proto text
84 | *.ps1 text eol=lf
85 | *.psd binary
86 | *.pxd text
87 | *.py text diff=python
88 | *.py3 text diff=python
89 | *.pyc binary
90 | *.pyd binary
91 | *.pyo binary
92 | *.pyw text diff=python
93 | *.pywz binary
94 | *.pyx text
95 | *.pyz binary
96 | *.rake text diff=ruby
97 | *.rar binary
98 | *.rb text diff=ruby
99 | *.rtf text diff=astextplain
100 | *.ruleset text
101 | *.sass text
102 | *.scss text
103 | *.sh text eol=lf
104 | *.sln text
105 | *.so binary
106 | *.sql text
107 | *.styl text
108 | *.svg text
109 | *.svgz binary
110 | *.tar binary
111 | *.targets text
112 | *.tex text diff=tex
113 | *.tif binary
114 | *.tiff binary
115 | *.ts text
116 | *.tsv text
117 | *.tsx text
118 | *.ttf binary
119 | *.txt text
120 | *.vbproj text
121 | *.war binary
122 | *.wav binary
123 | *.wbmp binary
124 | *.webm binary
125 | *.webp binary
126 | *.woff binary
127 | *.woff2 binary
128 | *.xhtml text diff=html
129 | *.xls binary
130 | *.xlsx binary
131 | *.xlt binary
132 | *.xltx binary
133 | *.xml text
134 | *.xslt text
135 | *.xz binary
136 | *.yaml text
137 | *.yml text
138 | *.zip binary
139 | .babelrc text
140 | .dockerignore text
141 | .editorconfig text
142 | .eslintrc text
143 | .gitattributes text
144 | .gitconfig text
145 | .gitignore text
146 | .helmignore text
147 | .htaccess text
148 | .nvmrc text eol=lf
149 | .prettierignore text
150 | .prettierrc text
151 | .yarnclean text
152 | .yarnrc text
153 | ACKNOWLEDGMENTS* text
154 | AUTHORS* text
155 | CHANGELOG* text
156 | CHANGES* text
157 | CODE_OF_CONDUCT* text
158 | CodeMaid.config text
159 | CODEOWNERS* text
160 | CONTRIBUTING* text
161 | CONTRIBUTORS* text
162 | COPYING* text
163 | COPYRIGHT* text
164 | Dockerfile* text
165 | HISTORY* text
166 | INSTALL* text
167 | ISSUE_TEMPLATE* text
168 | LICENSE* text
169 | Makefile text
170 | makefile text
171 | NEWS* text
172 | paket.dependencies text
173 | paket.references text
174 | PULL_REQUEST_TEMPLATE* text
175 | README* text
176 | RELEASES* text
177 | SUPPORT* text
178 | TODO* text
179 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Linux.gitignore
2 | ## https://github.com/github/gitignore
3 |
4 | *~
5 |
6 | # temporary files which can be created if a process still has a handle open of a deleted file
7 | .fuse_hidden*
8 |
9 | # KDE directory preferences
10 | .directory
11 |
12 | # Linux trash folder which might appear on any partition or disk
13 | .Trash-*
14 |
15 | # .nfs files are created when an open file is removed but is still being accessed
16 | .nfs*
17 |
18 | ## macOS.gitignore
19 | ## https://github.com/github/gitignore
20 |
21 | # General
22 | .DS_Store
23 | .AppleDouble
24 | .LSOverride
25 |
26 | # Icon must end with two \r
27 | Icon
28 |
29 | # Thumbnails
30 | ._*
31 |
32 | # Files that might appear in the root of a volume
33 | .DocumentRevisions-V100
34 | .fseventsd
35 | .Spotlight-V100
36 | .TemporaryItems
37 | .Trashes
38 | .VolumeIcon.icns
39 | .com.apple.timemachine.donotpresent
40 |
41 | # Directories potentially created on remote AFP share
42 | .AppleDB
43 | .AppleDesktop
44 | Network Trash Folder
45 | Temporary Items
46 | .apdisk
47 |
48 | ## Windows.gitignore
49 | ## https://github.com/github/gitignore
50 |
51 | # Windows thumbnail cache files
52 | Thumbs.db
53 | Thumbs.db:encryptable
54 | ehthumbs.db
55 | ehthumbs_vista.db
56 |
57 | # Dump file
58 | *.stackdump
59 |
60 | # Folder config file
61 | [Dd]esktop.ini
62 |
63 | # Recycle Bin used on file shares
64 | $RECYCLE.BIN/
65 |
66 | # Windows Installer files
67 | *.cab
68 | *.msi
69 | *.msix
70 | *.msm
71 | *.msp
72 |
73 | # Windows shortcuts
74 | *.lnk
75 |
76 | ## VisualStudio.gitignore
77 | ## https://github.com/github/gitignore
78 |
79 | ## Ignore Visual Studio temporary files, build results, and
80 | ## files generated by popular Visual Studio add-ons.
81 | ##
82 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
83 |
84 | # User-specific files
85 | *.rsuser
86 | *.suo
87 | *.user
88 | *.userosscache
89 | *.sln.docstates
90 |
91 | # User-specific files (MonoDevelop/Xamarin Studio)
92 | *.userprefs
93 |
94 | # Mono auto generated files
95 | mono_crash.*
96 |
97 | # Build results
98 | [Dd]ebug/
99 | [Dd]ebugPublic/
100 | [Rr]elease/
101 | [Rr]eleases/
102 | x64/
103 | x86/
104 | [Ww][Ii][Nn]32/
105 | [Aa][Rr][Mm]/
106 | [Aa][Rr][Mm]64/
107 | bld/
108 | [Bb]in/
109 | [Oo]bj/
110 | [Ll]og/
111 | [Ll]ogs/
112 |
113 | # Visual Studio 2015/2017 cache/options directory
114 | .vs/
115 | # Uncomment if you have tasks that create the project's static files in wwwroot
116 | #wwwroot/
117 |
118 | # Visual Studio 2017 auto generated files
119 | Generated\ Files/
120 |
121 | # MSTest test Results
122 | [Tt]est[Rr]esult*/
123 | [Bb]uild[Ll]og.*
124 |
125 | # NUnit
126 | *.VisualState.xml
127 | TestResult.xml
128 | nunit-*.xml
129 |
130 | # Build Results of an ATL Project
131 | [Dd]ebugPS/
132 | [Rr]eleasePS/
133 | dlldata.c
134 |
135 | # Benchmark Results
136 | BenchmarkDotNet.Artifacts/
137 |
138 | # .NET Core
139 | project.lock.json
140 | project.fragment.lock.json
141 | artifacts/
142 |
143 | # ASP.NET Scaffolding
144 | ScaffoldingReadMe.txt
145 |
146 | # StyleCop
147 | StyleCopReport.xml
148 |
149 | # Files built by Visual Studio
150 | *_i.c
151 | *_p.c
152 | *_h.h
153 | *.ilk
154 | *.meta
155 | *.obj
156 | *.iobj
157 | *.pch
158 | *.pdb
159 | *.ipdb
160 | *.pgc
161 | *.pgd
162 | *.rsp
163 | *.sbr
164 | *.tlb
165 | *.tli
166 | *.tlh
167 | *.tmp
168 | *.tmp_proj
169 | *_wpftmp.csproj
170 | *.log
171 | *.tlog
172 | *.vspscc
173 | *.vssscc
174 | .builds
175 | *.pidb
176 | *.svclog
177 | *.scc
178 |
179 | # Chutzpah Test files
180 | _Chutzpah*
181 |
182 | # Visual C++ cache files
183 | ipch/
184 | *.aps
185 | *.ncb
186 | *.opendb
187 | *.opensdf
188 | *.sdf
189 | *.cachefile
190 | *.VC.db
191 | *.VC.VC.opendb
192 |
193 | # Visual Studio profiler
194 | *.psess
195 | *.vsp
196 | *.vspx
197 | *.sap
198 |
199 | # Visual Studio Trace Files
200 | *.e2e
201 |
202 | # TFS 2012 Local Workspace
203 | $tf/
204 |
205 | # Guidance Automation Toolkit
206 | *.gpState
207 |
208 | # ReSharper is a .NET coding add-in
209 | _ReSharper*/
210 | *.[Rr]e[Ss]harper
211 | *.DotSettings.user
212 |
213 | # TeamCity is a build add-in
214 | _TeamCity*
215 |
216 | # DotCover is a Code Coverage Tool
217 | *.dotCover
218 |
219 | # AxoCover is a Code Coverage Tool
220 | .axoCover/*
221 | !.axoCover/settings.json
222 |
223 | # Coverlet is a free, cross platform Code Coverage Tool
224 | coverage*.json
225 | coverage*.xml
226 | coverage*.info
227 |
228 | # Visual Studio code coverage results
229 | *.coverage
230 | *.coveragexml
231 |
232 | # NCrunch
233 | _NCrunch_*
234 | .*crunch*.local.xml
235 | nCrunchTemp_*
236 |
237 | # MightyMoose
238 | *.mm.*
239 | AutoTest.Net/
240 |
241 | # Web workbench (sass)
242 | .sass-cache/
243 |
244 | # Installshield output folder
245 | [Ee]xpress/
246 |
247 | # DocProject is a documentation generator add-in
248 | DocProject/buildhelp/
249 | DocProject/Help/*.HxT
250 | DocProject/Help/*.HxC
251 | DocProject/Help/*.hhc
252 | DocProject/Help/*.hhk
253 | DocProject/Help/*.hhp
254 | DocProject/Help/Html2
255 | DocProject/Help/html
256 |
257 | # Click-Once directory
258 | publish/
259 |
260 | # Publish Web Output
261 | *.[Pp]ublish.xml
262 | *.azurePubxml
263 | # Note: Comment the next line if you want to checkin your web deploy settings,
264 | # but database connection strings (with potential passwords) will be unencrypted
265 | *.pubxml
266 | *.publishproj
267 |
268 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
269 | # checkin your Azure Web App publish settings, but sensitive information contained
270 | # in these scripts will be unencrypted
271 | PublishScripts/
272 |
273 | # NuGet Packages
274 | *.nupkg
275 | # NuGet Symbol Packages
276 | *.snupkg
277 | # The packages folder can be ignored because of Package Restore
278 | **/[Pp]ackages/*
279 | # except build/, which is used as an MSBuild target.
280 | !**/[Pp]ackages/build/
281 | # Uncomment if necessary however generally it will be regenerated when needed
282 | #!**/[Pp]ackages/repositories.config
283 | # NuGet v3's project.json files produces more ignorable files
284 | *.nuget.props
285 | *.nuget.targets
286 |
287 | # Nuget personal access tokens and Credentials
288 | nuget.config
289 |
290 | # Microsoft Azure Build Output
291 | csx/
292 | *.build.csdef
293 |
294 | # Microsoft Azure Emulator
295 | ecf/
296 | rcf/
297 |
298 | # Windows Store app package directories and files
299 | AppPackages/
300 | BundleArtifacts/
301 | Package.StoreAssociation.xml
302 | _pkginfo.txt
303 | *.appx
304 | *.appxbundle
305 | *.appxupload
306 |
307 | # Visual Studio cache files
308 | # files ending in .cache can be ignored
309 | *.[Cc]ache
310 | # but keep track of directories ending in .cache
311 | !?*.[Cc]ache/
312 |
313 | # Others
314 | ClientBin/
315 | ~$*
316 | *~
317 | *.dbmdl
318 | *.dbproj.schemaview
319 | *.jfm
320 | *.pfx
321 | *.publishsettings
322 | orleans.codegen.cs
323 |
324 | # Including strong name files can present a security risk
325 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
326 | #*.snk
327 |
328 | # Since there are multiple workflows, uncomment next line to ignore bower_components
329 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
330 | #bower_components/
331 |
332 | # RIA/Silverlight projects
333 | Generated_Code/
334 |
335 | # Backup & report files from converting an old project file
336 | # to a newer Visual Studio version. Backup files are not needed,
337 | # because we have git ;-)
338 | _UpgradeReport_Files/
339 | Backup*/
340 | UpgradeLog*.XML
341 | UpgradeLog*.htm
342 | ServiceFabricBackup/
343 | *.rptproj.bak
344 |
345 | # SQL Server files
346 | *.mdf
347 | *.ldf
348 | *.ndf
349 |
350 | # Business Intelligence projects
351 | *.rdl.data
352 | *.bim.layout
353 | *.bim_*.settings
354 | *.rptproj.rsuser
355 | *- [Bb]ackup.rdl
356 | *- [Bb]ackup ([0-9]).rdl
357 | *- [Bb]ackup ([0-9][0-9]).rdl
358 |
359 | # Microsoft Fakes
360 | FakesAssemblies/
361 |
362 | # GhostDoc plugin setting file
363 | *.GhostDoc.xml
364 |
365 | # Node.js Tools for Visual Studio
366 | .ntvs_analysis.dat
367 | node_modules/
368 |
369 | # Visual Studio 6 build log
370 | *.plg
371 |
372 | # Visual Studio 6 workspace options file
373 | *.opt
374 |
375 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
376 | *.vbw
377 |
378 | # Visual Studio LightSwitch build output
379 | **/*.HTMLClient/GeneratedArtifacts
380 | **/*.DesktopClient/GeneratedArtifacts
381 | **/*.DesktopClient/ModelManifest.xml
382 | **/*.Server/GeneratedArtifacts
383 | **/*.Server/ModelManifest.xml
384 | _Pvt_Extensions
385 |
386 | # Paket dependency manager
387 | .paket/paket.exe
388 | paket-files/
389 |
390 | # FAKE - F# Make
391 | .fake/
392 |
393 | # CodeRush personal settings
394 | .cr/personal
395 |
396 | # Python Tools for Visual Studio (PTVS)
397 | __pycache__/
398 | *.pyc
399 |
400 | # Cake - Uncomment if you are using it
401 | # tools/**
402 | # !tools/packages.config
403 |
404 | # Tabs Studio
405 | *.tss
406 |
407 | # Telerik's JustMock configuration file
408 | *.jmconfig
409 |
410 | # BizTalk build output
411 | *.btp.cs
412 | *.btm.cs
413 | *.odx.cs
414 | *.xsd.cs
415 |
416 | # OpenCover UI analysis results
417 | OpenCover/
418 |
419 | # Azure Stream Analytics local run output
420 | ASALocalRun/
421 |
422 | # MSBuild Binary and Structured Log
423 | *.binlog
424 |
425 | # NVidia Nsight GPU debugger configuration file
426 | *.nvuser
427 |
428 | # MFractors (Xamarin productivity tool) working folder
429 | .mfractor/
430 |
431 | # Local History for Visual Studio
432 | .localhistory/
433 |
434 | # BeatPulse healthcheck temp database
435 | healthchecksdb
436 |
437 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
438 | MigrationBackup/
439 |
440 | # Ionide (cross platform F# VS Code tools) working folder
441 | .ionide/
442 |
443 | # Fody - auto-generated XML schema
444 | FodyWeavers.xsd
445 |
446 | # VS Code files for those working on multiple tools
447 | .vscode/*
448 | !.vscode/settings.json
449 | !.vscode/tasks.json
450 | !.vscode/launch.json
451 | !.vscode/extensions.json
452 | *.code-workspace
453 |
454 | # Local History for Visual Studio Code
455 | .history/
456 |
457 | # Windows Installer files from build outputs
458 | *.cab
459 | *.msi
460 | *.msix
461 | *.msm
462 | *.msp
463 |
464 | # JetBrains Rider
465 | .idea/
466 | *.sln.iml
467 |
468 | ## VisualStudioCode.gitignore
469 | ## https://github.com/github/gitignore
470 |
471 | .vscode/*
472 | !.vscode/settings.json
473 | !.vscode/tasks.json
474 | !.vscode/launch.json
475 | !.vscode/extensions.json
476 | *.code-workspace
477 |
478 | # Local History for Visual Studio Code
479 | .history/
480 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "dotnet-test-explorer.runInParallel": true,
3 | "dotnet-test-explorer.testProjectPath": "/test/*.Tests",
4 | "editor.formatOnSave": true,
5 | "editor.minimap.maxColumn": 120,
6 | "editor.minimap.showSlider": "always",
7 | "editor.renderWhitespace": "all",
8 | "editor.rulers": [
9 | 120
10 | ],
11 | "files.autoSave": "afterDelay",
12 | "files.autoSaveDelay": 30000,
13 | "files.exclude": {
14 | "**/bin": true,
15 | "**/obj": true
16 | },
17 | "omnisharp.defaultLaunchSolution": "supertokens-dotnet.sln",
18 | "omnisharp.enableEditorConfigSupport": true,
19 | "omnisharp.enableRoslynAnalyzers": true,
20 | "omnisharp.useEditorFormattingSettings": false
21 | }
22 |
--------------------------------------------------------------------------------
/CodeMaid.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | True
12 |
13 |
14 | True
15 |
16 |
17 | True
18 |
19 |
20 | True
21 |
22 |
23 | True
24 |
25 |
26 | False
27 |
28 |
29 | 2
30 |
31 |
32 | True
33 |
34 |
35 | True
36 |
37 |
38 | False
39 |
40 |
41 | 120
42 |
43 |
44 | False
45 |
46 |
47 | True
48 |
49 |
50 | False
51 |
52 |
53 | False
54 |
55 |
56 | False
57 |
58 |
59 | False
60 |
61 |
62 | 4
63 |
64 |
65 | True
66 |
67 |
68 | True
69 |
70 |
71 | True
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {9A19103F-16F7-4668-BE54-9A1E7A4F7556}
6 |
7 |
8 |
9 |
10 | $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | Copyright 2021 Salad Technologies, Inc. (https://salad.com)
179 |
180 | Licensed under the Apache License, Version 2.0 (the "License");
181 | you may not use this file except in compliance with the License.
182 | You may obtain a copy of the License at
183 |
184 | http://www.apache.org/licenses/LICENSE-2.0
185 |
186 | Unless required by applicable law or agreed to in writing, software
187 | distributed under the License is distributed on an "AS IS" BASIS,
188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
189 | See the License for the specific language governing permissions and
190 | limitations under the License.
191 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SuperTokens for ASP.NET Core
2 |
3 | **NOTE**: _This repository is no longer supported or updated by Salad Technologies. If you wish to continue to develop this code yourself, we recommend you fork it._
4 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "allowPrerelease": true,
4 | "rollForward": "latestFeature",
5 | "version": "5.0.400"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/omnisharp.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/omnisharp",
3 | "FormattingOptions": {
4 | "enableEditorConfigSupport": true
5 | },
6 | "RoslynExtensionsOptions": {
7 | "enableAnalyzersSupport": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/paket.dependencies:
--------------------------------------------------------------------------------
1 | framework: net5.0
2 | storage: none
3 |
4 | source https://api.nuget.org/v3/index.json
5 |
6 | nuget coverlet.collector copy_local: true
7 | nuget Microsoft.AspNetCore.Mvc.Testing
8 | nuget Microsoft.CodeAnalysis.NetAnalyzers copy_local: true
9 | nuget Microsoft.NET.Test.Sdk copy_local: true
10 | nuget Microsoft.SourceLink.GitHub copy_local: true
11 | nuget Newtonsoft.Json
12 | nuget SonarAnalyzer.CSharp copy_local: true
13 | nuget xunit
14 | nuget xunit.runner.visualstudio copy_local: true
15 |
--------------------------------------------------------------------------------
/paket.lock:
--------------------------------------------------------------------------------
1 | STORAGE: NONE
2 | RESTRICTION: == net5.0
3 | NUGET
4 | remote: https://api.nuget.org/v3/index.json
5 | coverlet.collector (3.1) - copy_local: true
6 | Microsoft.AspNetCore.Mvc.Testing (5.0.10)
7 | Microsoft.AspNetCore.TestHost (>= 5.0.10)
8 | Microsoft.Extensions.DependencyModel (>= 5.0)
9 | Microsoft.Extensions.Hosting (>= 5.0)
10 | Microsoft.AspNetCore.TestHost (5.0.10)
11 | System.IO.Pipelines (>= 5.0.1)
12 | Microsoft.Build.Tasks.Git (1.0) - copy_local: true
13 | Microsoft.CodeAnalysis.NetAnalyzers (5.0.3) - copy_local: true
14 | Microsoft.CodeCoverage (16.11) - copy_local: true
15 | Microsoft.Extensions.Configuration (5.0)
16 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
17 | Microsoft.Extensions.Primitives (>= 5.0)
18 | Microsoft.Extensions.Configuration.Abstractions (5.0)
19 | Microsoft.Extensions.Primitives (>= 5.0)
20 | Microsoft.Extensions.Configuration.Binder (5.0)
21 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
22 | Microsoft.Extensions.Configuration.CommandLine (5.0)
23 | Microsoft.Extensions.Configuration (>= 5.0)
24 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
25 | Microsoft.Extensions.Configuration.EnvironmentVariables (5.0)
26 | Microsoft.Extensions.Configuration (>= 5.0)
27 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
28 | Microsoft.Extensions.Configuration.FileExtensions (5.0)
29 | Microsoft.Extensions.Configuration (>= 5.0)
30 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
31 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
32 | Microsoft.Extensions.FileProviders.Physical (>= 5.0)
33 | Microsoft.Extensions.Primitives (>= 5.0)
34 | Microsoft.Extensions.Configuration.Json (5.0)
35 | Microsoft.Extensions.Configuration (>= 5.0)
36 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
37 | Microsoft.Extensions.Configuration.FileExtensions (>= 5.0)
38 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
39 | Microsoft.Extensions.Configuration.UserSecrets (5.0)
40 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
41 | Microsoft.Extensions.Configuration.Json (>= 5.0)
42 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
43 | Microsoft.Extensions.FileProviders.Physical (>= 5.0)
44 | Microsoft.Extensions.DependencyInjection (5.0.2)
45 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
46 | Microsoft.Extensions.DependencyInjection.Abstractions (5.0)
47 | Microsoft.Extensions.DependencyModel (5.0)
48 | Microsoft.Extensions.FileProviders.Abstractions (5.0)
49 | Microsoft.Extensions.Primitives (>= 5.0)
50 | Microsoft.Extensions.FileProviders.Physical (5.0)
51 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
52 | Microsoft.Extensions.FileSystemGlobbing (>= 5.0)
53 | Microsoft.Extensions.Primitives (>= 5.0)
54 | Microsoft.Extensions.FileSystemGlobbing (5.0)
55 | Microsoft.Extensions.Hosting (5.0)
56 | Microsoft.Extensions.Configuration (>= 5.0)
57 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
58 | Microsoft.Extensions.Configuration.Binder (>= 5.0)
59 | Microsoft.Extensions.Configuration.CommandLine (>= 5.0)
60 | Microsoft.Extensions.Configuration.EnvironmentVariables (>= 5.0)
61 | Microsoft.Extensions.Configuration.FileExtensions (>= 5.0)
62 | Microsoft.Extensions.Configuration.Json (>= 5.0)
63 | Microsoft.Extensions.Configuration.UserSecrets (>= 5.0)
64 | Microsoft.Extensions.DependencyInjection (>= 5.0)
65 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
66 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
67 | Microsoft.Extensions.FileProviders.Physical (>= 5.0)
68 | Microsoft.Extensions.Hosting.Abstractions (>= 5.0)
69 | Microsoft.Extensions.Logging (>= 5.0)
70 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
71 | Microsoft.Extensions.Logging.Configuration (>= 5.0)
72 | Microsoft.Extensions.Logging.Console (>= 5.0)
73 | Microsoft.Extensions.Logging.Debug (>= 5.0)
74 | Microsoft.Extensions.Logging.EventLog (>= 5.0)
75 | Microsoft.Extensions.Logging.EventSource (>= 5.0)
76 | Microsoft.Extensions.Options (>= 5.0)
77 | Microsoft.Extensions.Hosting.Abstractions (5.0)
78 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
79 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
80 | Microsoft.Extensions.FileProviders.Abstractions (>= 5.0)
81 | Microsoft.Extensions.Logging (5.0)
82 | Microsoft.Extensions.DependencyInjection (>= 5.0)
83 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
84 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
85 | Microsoft.Extensions.Options (>= 5.0)
86 | Microsoft.Extensions.Logging.Abstractions (5.0)
87 | Microsoft.Extensions.Logging.Configuration (5.0)
88 | Microsoft.Extensions.Configuration (>= 5.0)
89 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
90 | Microsoft.Extensions.Configuration.Binder (>= 5.0)
91 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
92 | Microsoft.Extensions.Logging (>= 5.0)
93 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
94 | Microsoft.Extensions.Options (>= 5.0)
95 | Microsoft.Extensions.Options.ConfigurationExtensions (>= 5.0)
96 | Microsoft.Extensions.Logging.Console (5.0)
97 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
98 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
99 | Microsoft.Extensions.Logging (>= 5.0)
100 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
101 | Microsoft.Extensions.Logging.Configuration (>= 5.0)
102 | Microsoft.Extensions.Options (>= 5.0)
103 | Microsoft.Extensions.Options.ConfigurationExtensions (>= 5.0)
104 | Microsoft.Extensions.Logging.Debug (5.0)
105 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
106 | Microsoft.Extensions.Logging (>= 5.0)
107 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
108 | Microsoft.Extensions.Logging.EventLog (5.0)
109 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
110 | Microsoft.Extensions.Logging (>= 5.0)
111 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
112 | Microsoft.Extensions.Options (>= 5.0)
113 | System.Diagnostics.EventLog (>= 5.0)
114 | Microsoft.Extensions.Logging.EventSource (5.0.1)
115 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
116 | Microsoft.Extensions.Logging (>= 5.0)
117 | Microsoft.Extensions.Logging.Abstractions (>= 5.0)
118 | Microsoft.Extensions.Options (>= 5.0)
119 | Microsoft.Extensions.Primitives (>= 5.0.1)
120 | Microsoft.Extensions.Options (5.0)
121 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
122 | Microsoft.Extensions.Primitives (>= 5.0)
123 | Microsoft.Extensions.Options.ConfigurationExtensions (5.0)
124 | Microsoft.Extensions.Configuration.Abstractions (>= 5.0)
125 | Microsoft.Extensions.Configuration.Binder (>= 5.0)
126 | Microsoft.Extensions.DependencyInjection.Abstractions (>= 5.0)
127 | Microsoft.Extensions.Options (>= 5.0)
128 | Microsoft.Extensions.Primitives (>= 5.0)
129 | Microsoft.Extensions.Primitives (5.0.1)
130 | Microsoft.NET.Test.Sdk (16.11) - copy_local: true
131 | Microsoft.CodeCoverage (>= 16.11)
132 | Microsoft.TestPlatform.TestHost (>= 16.11)
133 | Microsoft.NETCore.Platforms (5.0.3)
134 | Microsoft.SourceLink.Common (1.0) - copy_local: true
135 | Microsoft.SourceLink.GitHub (1.0) - copy_local: true
136 | Microsoft.Build.Tasks.Git (>= 1.0)
137 | Microsoft.SourceLink.Common (>= 1.0)
138 | Microsoft.TestPlatform.ObjectModel (16.11) - copy_local: true
139 | NuGet.Frameworks (>= 5.0)
140 | System.Reflection.Metadata (>= 1.6)
141 | Microsoft.TestPlatform.TestHost (16.11) - copy_local: true
142 | Microsoft.TestPlatform.ObjectModel (>= 16.11)
143 | Newtonsoft.Json (>= 9.0.1)
144 | Microsoft.Win32.Registry (5.0)
145 | System.Security.AccessControl (>= 5.0)
146 | System.Security.Principal.Windows (>= 5.0)
147 | NETStandard.Library (2.0.3)
148 | Microsoft.NETCore.Platforms (>= 1.1)
149 | Newtonsoft.Json (13.0.1)
150 | NuGet.Frameworks (5.11) - copy_local: true
151 | SonarAnalyzer.CSharp (8.29.0.36737) - copy_local: true
152 | System.Diagnostics.EventLog (5.0.1)
153 | Microsoft.NETCore.Platforms (>= 5.0.1)
154 | Microsoft.Win32.Registry (>= 5.0)
155 | System.Security.Principal.Windows (>= 5.0)
156 | System.IO.Pipelines (5.0.1)
157 | System.Reflection.Metadata (5.0) - copy_local: true
158 | System.Security.AccessControl (5.0)
159 | Microsoft.NETCore.Platforms (>= 5.0)
160 | System.Security.Principal.Windows (>= 5.0)
161 | System.Security.Principal.Windows (5.0)
162 | xunit (2.4.1)
163 | xunit.analyzers (>= 0.10)
164 | xunit.assert (2.4.1)
165 | xunit.core (2.4.1)
166 | xunit.abstractions (2.0.3)
167 | xunit.analyzers (0.10)
168 | xunit.assert (2.4.1)
169 | NETStandard.Library (>= 1.6.1)
170 | xunit.core (2.4.1)
171 | xunit.extensibility.core (2.4.1)
172 | xunit.extensibility.execution (2.4.1)
173 | xunit.extensibility.core (2.4.1)
174 | NETStandard.Library (>= 1.6.1)
175 | xunit.abstractions (>= 2.0.3)
176 | xunit.extensibility.execution (2.4.1)
177 | NETStandard.Library (>= 1.6.1)
178 | xunit.extensibility.core (2.4.1)
179 | xunit.runner.visualstudio (2.4.3) - copy_local: true
180 |
--------------------------------------------------------------------------------
/scripts/build.ps1:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pwsh
2 | [CmdletBinding()]
3 | param()
4 |
5 | Set-StrictMode -Version Latest
6 | $ErrorActionPreference = "Stop"
7 |
8 | # Build Docker images
9 | $ProjectRoot = Split-Path -Path $PSScriptRoot -Parent
10 | Push-Location -Path $ProjectRoot
11 | try {
12 | & dotnet tool restore
13 | & dotnet paket restore
14 | & dotnet restore .\supertokens-dotnet.sln
15 | & dotnet build --configuration Release --no-dependencies --no-restore .\src\SuperTokens.Net\SuperTokens.Net.csproj
16 | & dotnet build --configuration Release --no-dependencies --no-restore .\src\SuperTokens.AspNetCore\SuperTokens.AspNetCore.csproj
17 | & dotnet pack --configuration Release --no-build --no-dependencies --no-restore --output "$(Join-Path -Path $ProjectRoot -ChildPath artifacts)" .\src\SuperTokens.Net\SuperTokens.Net.csproj
18 | & dotnet pack --configuration Release --no-build --no-dependencies --no-restore --output "$(Join-Path -Path $ProjectRoot -ChildPath artifacts)" .\src\SuperTokens.AspNetCore\SuperTokens.AspNetCore.csproj
19 | }
20 | finally {
21 | Pop-Location
22 | }
23 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/AccessToken.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SuperTokens.AspNetCore
4 | {
5 | internal sealed class AccessToken
6 | {
7 | public AccessToken(
8 | string? antiCsrfToken,
9 | DateTimeOffset expiryTime,
10 | string? parentRefreshTokenHash1,
11 | string refreshTokenHash1,
12 | string sessionHandle,
13 | DateTimeOffset timeCreated,
14 | string userData,
15 | string userId)
16 | {
17 | this.AntiCsrfToken = antiCsrfToken;
18 | this.ExpiryTime = expiryTime;
19 | this.ParentRefreshTokenHash1 = parentRefreshTokenHash1;
20 | this.RefreshTokenHash1 = refreshTokenHash1;
21 | this.SessionHandle = sessionHandle;
22 | this.TimeCreated = timeCreated;
23 | this.UserData = userData;
24 | this.UserId = userId;
25 | }
26 |
27 | public string? AntiCsrfToken { get; }
28 |
29 | public DateTimeOffset ExpiryTime { get; }
30 |
31 | public string? ParentRefreshTokenHash1 { get; }
32 |
33 | public string RefreshTokenHash1 { get; }
34 |
35 | public string SessionHandle { get; }
36 |
37 | public DateTimeOffset TimeCreated { get; }
38 |
39 | public string UserData { get; }
40 |
41 | public string UserId { get; }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/AccessTokenSigningKey.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SuperTokens.AspNetCore
4 | {
5 | public sealed class AccessTokenSigningKey : IEquatable
6 | {
7 | public AccessTokenSigningKey(
8 | string publicKey,
9 | DateTimeOffset expiration,
10 | DateTimeOffset creation)
11 | {
12 | this.PublicKey = publicKey;
13 | this.Expiration = expiration;
14 | this.Creation = creation;
15 | }
16 |
17 | public DateTimeOffset Creation { get; }
18 |
19 | public DateTimeOffset Expiration { get; }
20 |
21 | public string PublicKey { get; }
22 |
23 | public override bool Equals(object? obj) => this.Equals(obj as AccessTokenSigningKey);
24 |
25 | // We do not consider the creation time during equality check: this information is not available on old APIs.
26 | public bool Equals(AccessTokenSigningKey? other) => other != null && this.PublicKey == other.PublicKey && this.Expiration.Equals(other.Expiration);
27 |
28 | public override int GetHashCode() => HashCode.Combine(this.PublicKey, this.Expiration, this.Creation);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/AccessTokenUtilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using System.Text.Json;
4 |
5 | namespace SuperTokens.AspNetCore
6 | {
7 | internal static class AccessTokenUtilities
8 | {
9 | public static bool TryParse(string jwtPayload, [NotNullWhen(true)] out AccessToken? accessToken)
10 | {
11 | using var document = JsonDocument.Parse(jwtPayload);
12 | if (!document.RootElement.TryGetProperty("sessionHandle", out var sessionHandleProperty) || sessionHandleProperty.ValueKind != JsonValueKind.String ||
13 | !document.RootElement.TryGetProperty("userId", out var userIdProperty) || userIdProperty.ValueKind != JsonValueKind.String ||
14 | !document.RootElement.TryGetProperty("refreshTokenHash1", out var refreshTokenHash1Property) || refreshTokenHash1Property.ValueKind != JsonValueKind.String ||
15 | (document.RootElement.TryGetProperty("parentRefreshTokenHash1", out var parentRefreshTokenHash1Property) && parentRefreshTokenHash1Property.ValueKind != JsonValueKind.String) ||
16 | !document.RootElement.TryGetProperty("userData", out var userDataProperty) || userDataProperty.ValueKind != JsonValueKind.Object ||
17 | (document.RootElement.TryGetProperty("antiCsrfToken", out var antiCsrfTokenProperty) && antiCsrfTokenProperty.ValueKind != JsonValueKind.String) ||
18 | !document.RootElement.TryGetProperty("expiryTime", out var expiryTimeProperty) || expiryTimeProperty.ValueKind != JsonValueKind.Number ||
19 | !document.RootElement.TryGetProperty("timeCreated", out var timeCreatedProperty) || timeCreatedProperty.ValueKind != JsonValueKind.Number)
20 | {
21 | accessToken = null;
22 | return false;
23 | }
24 |
25 | try
26 | {
27 | accessToken = new AccessToken(
28 | antiCsrfTokenProperty.ValueKind == JsonValueKind.Undefined ? null : antiCsrfTokenProperty.GetString()!.Trim(),
29 | DateTimeOffset.FromUnixTimeMilliseconds(expiryTimeProperty.GetInt64()),
30 | parentRefreshTokenHash1Property.ValueKind == JsonValueKind.Undefined ? null : parentRefreshTokenHash1Property.GetString()!.Trim(),
31 | refreshTokenHash1Property.GetString()!.Trim(),
32 | sessionHandleProperty.GetString()!.Trim(),
33 | DateTimeOffset.FromUnixTimeMilliseconds(timeCreatedProperty.GetInt64()),
34 | userDataProperty.GetRawText().Trim(),
35 | userIdProperty.GetString()!.Trim());
36 | return true;
37 | }
38 | catch (ArgumentOutOfRangeException)
39 | {
40 | accessToken = null;
41 | return false;
42 | }
43 | catch (FormatException)
44 | {
45 | accessToken = null;
46 | return false;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/ApiVersionContainer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Authentication;
6 | using Microsoft.Extensions.DependencyInjection;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 | using Microsoft.Extensions.Options;
10 | using SuperTokens.Net;
11 |
12 | namespace SuperTokens.AspNetCore
13 | {
14 | internal sealed class ApiVersionContainer : BackgroundService, IApiVersionContainer
15 | {
16 | private static readonly TimeSpan AutomaticRefreshInterval = new(0, 12, 0, 0, 0);
17 |
18 | private static readonly TimeSpan MinAutomaticRefreshInterval = new(0, 0, 1, 0, 0);
19 |
20 | private static readonly TimeSpan RetryRefreshInterval = new(0, 0, 5, 0, 0);
21 |
22 | private static readonly string[] SupportedApiVersions = new[] { "2.9", "2.8", "2.7" }.OrderByDescending(str => new Version(str)).ToArray();
23 |
24 | private readonly ISystemClock _clock;
25 |
26 | private readonly ILogger _logger;
27 |
28 | private readonly IOptionsMonitor _options;
29 |
30 | private readonly SemaphoreSlim _refreshLock = new(1);
31 |
32 | private readonly IServiceProvider _services;
33 |
34 | private string? _apiVersion;
35 |
36 | private DateTimeOffset _refreshAfter = DateTimeOffset.MinValue;
37 |
38 | public ApiVersionContainer(IServiceProvider services, ISystemClock clock, IOptionsMonitor options, ILogger logger)
39 | {
40 | _services = services ?? throw new ArgumentNullException(nameof(services));
41 | _clock = clock ?? throw new ArgumentNullException(nameof(clock));
42 | _options = options ?? throw new ArgumentNullException(nameof(options));
43 | _logger = logger ?? throw new ArgumentNullException(nameof(logger));
44 | }
45 |
46 | public ValueTask GetApiVersionAsync(string? apiKey) =>
47 | this.GetApiVersionAsync(apiKey, CancellationToken.None);
48 |
49 | public ValueTask GetApiVersionAsync(string? apiKey, CancellationToken cancellationToken)
50 | {
51 | var apiVersion = _apiVersion;
52 | return apiVersion != null
53 | ? ValueTask.FromResult(apiVersion)
54 | : new ValueTask(this.RefreshApiVersionAsync(apiKey, cancellationToken));
55 | }
56 |
57 | protected override async Task ExecuteAsync(CancellationToken stoppingToken)
58 | {
59 | while (true)
60 | {
61 | stoppingToken.ThrowIfCancellationRequested();
62 |
63 | try
64 | {
65 | var options = _options.Get(SuperTokensDefaults.AuthenticationScheme);
66 | await this.RefreshApiVersionAsync(options.CoreApiKey, stoppingToken);
67 | }
68 | catch (Exception e)
69 | {
70 | _logger.LogError(e, "Failed to obtain API versions from SuperTokens Core.");
71 | }
72 |
73 | var delay = _refreshAfter - _clock.UtcNow;
74 | if (delay < MinAutomaticRefreshInterval)
75 | {
76 | delay = MinAutomaticRefreshInterval;
77 | }
78 |
79 | await Task.Delay(delay, stoppingToken);
80 | }
81 | }
82 |
83 | private static NotSupportedException NewNotSupportedException(Exception? innerException = null) =>
84 | new("This version of the SuperTokens SDK does not support the specified SuperTokens Core.", innerException);
85 |
86 | private async Task RefreshApiVersionAsync(string? apiKey, CancellationToken cancellationToken)
87 | {
88 | var now = _clock.UtcNow;
89 |
90 | await _refreshLock.WaitAsync(cancellationToken).ConfigureAwait(false);
91 | try
92 | {
93 | if (_refreshAfter <= now)
94 | {
95 | var coreApiClient = _services.GetRequiredService();
96 | try
97 | {
98 | var result = await coreApiClient.GetApiVersionAsync(apiKey, CancellationToken.None);
99 | string? matchedApiVersion = null;
100 | foreach (var supportedVersion in SupportedApiVersions)
101 | {
102 | foreach (var version in result.Versions)
103 | {
104 | if (supportedVersion.Equals(version, StringComparison.Ordinal))
105 | {
106 | matchedApiVersion = version;
107 | break;
108 | }
109 | }
110 |
111 | if (matchedApiVersion != null)
112 | {
113 | break;
114 | }
115 | }
116 |
117 | _apiVersion = matchedApiVersion;
118 | _refreshAfter = now.Add(AutomaticRefreshInterval);
119 | }
120 | catch (Exception e)
121 | {
122 | _refreshAfter = now.Add(RetryRefreshInterval);
123 | if (_apiVersion == null)
124 | {
125 | throw NewNotSupportedException(e);
126 | }
127 | else
128 | {
129 | _logger.LogError(e, "Failed to obtain updated API versions from SuperTokens Core.");
130 | }
131 | }
132 | }
133 |
134 | if (_apiVersion == null)
135 | {
136 | throw NewNotSupportedException();
137 | }
138 |
139 | return _apiVersion;
140 | }
141 | finally
142 | {
143 | _refreshLock.Release();
144 | }
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/DependencyInjection/SuperTokensExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Authentication;
3 | using Microsoft.Extensions.DependencyInjection.Extensions;
4 | using Microsoft.Extensions.Options;
5 | using SuperTokens.AspNetCore;
6 | using SuperTokens.Net;
7 |
8 | namespace Microsoft.Extensions.DependencyInjection
9 | {
10 | public static class SuperTokensExtensions
11 | {
12 | ///
13 | /// Adds SuperTokens authentication to using the default scheme (
14 | /// ).
15 | ///
16 | /// The .
17 | /// A reference to after the operation has completed.
18 | public static AuthenticationBuilder AddSuperTokens(this AuthenticationBuilder builder) =>
19 | builder.AddSuperTokens(SuperTokensDefaults.AuthenticationScheme);
20 |
21 | ///
22 | /// Adds SuperTokens authentication to using the specified scheme.
23 | ///
24 | /// The .
25 | /// The authentication scheme.
26 | /// A reference to after the operation has completed.
27 | public static AuthenticationBuilder AddSuperTokens(this AuthenticationBuilder builder, string authenticationScheme) =>
28 | builder.AddSuperTokens(authenticationScheme, null, null!);
29 |
30 | ///
31 | /// Adds SuperTokens authentication to using the default scheme (
32 | /// ).
33 | ///
34 | /// The .
35 | /// A delegate to configure .
36 | /// A reference to after the operation has completed.
37 | public static AuthenticationBuilder AddSuperTokens(this AuthenticationBuilder builder, Action configureOptions) =>
38 | builder.AddSuperTokens(SuperTokensDefaults.AuthenticationScheme, null, configureOptions);
39 |
40 | ///
41 | /// Adds SuperTokens authentication to using the specified scheme.
42 | ///
43 | /// The .
44 | /// The authentication scheme.
45 | /// A delegate to configure .
46 | /// A reference to after the operation has completed.
47 | public static AuthenticationBuilder AddSuperTokens(this AuthenticationBuilder builder, string authenticationScheme, Action configureOptions) =>
48 | builder.AddSuperTokens(authenticationScheme, null, configureOptions);
49 |
50 | ///
51 | /// Adds SuperTokens authentication to using the specified scheme.
52 | ///
53 | /// The .
54 | /// The authentication scheme.
55 | /// A display name for the authentication handler.
56 | /// A delegate to configure .
57 | /// A reference to after the operation has completed.
58 | public static AuthenticationBuilder AddSuperTokens(this AuthenticationBuilder builder, string authenticationScheme, string? displayName, Action configureOptions)
59 | {
60 | if (builder == null)
61 | {
62 | throw new ArgumentNullException(nameof(builder));
63 | }
64 |
65 | builder.Services.AddSingleton();
66 | builder.Services.AddSingleton(services => services.GetRequiredService());
67 | builder.Services.AddHostedService(services => services.GetRequiredService());
68 | builder.Services.AddSingleton();
69 | builder.Services.AddScoped();
70 | builder.Services.AddScoped();
71 | builder.Services.AddHttpClient((services, httpClient) =>
72 | {
73 | var options = services.GetRequiredService>().Get(authenticationScheme);
74 | httpClient.BaseAddress = new Uri(options.CoreAddress, UriKind.Absolute);
75 | });
76 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton, SuperTokensPostConfigureOptions>());
77 | return builder.AddScheme(authenticationScheme, displayName, configureOptions);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/Events/MessageReceivedContext.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authentication;
2 | using Microsoft.AspNetCore.Http;
3 |
4 | namespace SuperTokens.AspNetCore.Events
5 | {
6 | public class MessageReceivedContext : ResultContext
7 | {
8 | public MessageReceivedContext(HttpContext context, AuthenticationScheme scheme, SuperTokensOptions options) :
9 | base(context, scheme, options)
10 | {
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/Events/SuperTokensEvents.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace SuperTokens.AspNetCore.Events
5 | {
6 | public class SuperTokensEvents
7 | {
8 | public Func OnMessageReceived { get; set; } = context => Task.CompletedTask;
9 |
10 | public virtual Task MessageReceived(MessageReceivedContext context) =>
11 | this.OnMessageReceived(context);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/Handshake.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Immutable;
4 | using System.Linq;
5 |
6 | namespace SuperTokens.AspNetCore
7 | {
8 | public sealed class Handshake
9 | {
10 | private ImmutableArray _accessTokenSigningPublicKeyList;
11 |
12 | public Handshake(
13 | IEnumerable jwtSigningPublicKeyList,
14 | bool accessTokenBlacklistingEnabled,
15 | TimeSpan accessTokenLifetime,
16 | TimeSpan refreshTokenLifetime)
17 | {
18 | _accessTokenSigningPublicKeyList = ImmutableArray.ToImmutableArray(jwtSigningPublicKeyList);
19 |
20 | this.AccessTokenBlacklistingEnabled = accessTokenBlacklistingEnabled;
21 | this.AccessTokenLifetime = accessTokenLifetime;
22 | this.RefreshTokenLifetime = refreshTokenLifetime;
23 | }
24 |
25 | public bool AccessTokenBlacklistingEnabled { get; }
26 |
27 | public TimeSpan AccessTokenLifetime { get; }
28 |
29 | public TimeSpan RefreshTokenLifetime { get; }
30 |
31 | public ImmutableArray GetAccessTokenSigningPublicKeyList(DateTimeOffset now) =>
32 | _accessTokenSigningPublicKeyList.Where(keyInfo => keyInfo.Expiration > now).ToImmutableArray();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/HandshakeContainer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net.Http;
5 | using System.Text.Json;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 | using Microsoft.AspNetCore.Authentication;
9 | using Microsoft.Extensions.Logging;
10 | using SuperTokens.Net;
11 |
12 | namespace SuperTokens.AspNetCore
13 | {
14 | internal class HandshakeContainer : IHandshakeContainer
15 | {
16 | private readonly ISystemClock _clock;
17 |
18 | private readonly ICoreApiClient _coreApiClient;
19 |
20 | private readonly ILogger _logger;
21 | private readonly SemaphoreSlim _refreshLock = new(1);
22 |
23 | private Handshake? _handshake;
24 |
25 | public HandshakeContainer(ICoreApiClient coreApiClient, ILogger logger, ISystemClock clock)
26 | {
27 | _coreApiClient = coreApiClient ?? throw new ArgumentNullException(nameof(coreApiClient));
28 | _logger = logger ?? throw new ArgumentNullException(nameof(logger));
29 | _clock = clock ?? throw new ArgumentNullException(nameof(clock));
30 | }
31 |
32 | public Task GetHandshakeAsync(string? apiKey, string? cdiVersion) =>
33 | this.GetHandshakeAsync(apiKey, cdiVersion, CancellationToken.None);
34 |
35 | public async Task GetHandshakeAsync(string? apiKey, string? cdiVersion, CancellationToken cancellationToken)
36 | {
37 | var now = _clock.UtcNow;
38 |
39 | var handshake = _handshake;
40 | if (handshake != null && handshake.GetAccessTokenSigningPublicKeyList(now).Length > 0)
41 | {
42 | return handshake;
43 | }
44 |
45 | await _refreshLock.WaitAsync(cancellationToken).ConfigureAwait(false);
46 | try
47 | {
48 | if (_handshake == null || _handshake.GetAccessTokenSigningPublicKeyList(now).Length == 0)
49 | {
50 | try
51 | {
52 | var handshakeResponse = await _coreApiClient.GetHandshakeAsync(apiKey, cdiVersion, CancellationToken.None).ConfigureAwait(false);
53 | if (handshakeResponse.Status.Equals("OK", StringComparison.OrdinalIgnoreCase))
54 | {
55 | var jwtSigningPublicKeyList = handshakeResponse.JwtSigningPublicKeyList != null ?
56 | handshakeResponse.JwtSigningPublicKeyList.Select(keyInfo =>
57 | new AccessTokenSigningKey(keyInfo.publicKey,
58 | DateTimeOffset.FromUnixTimeMilliseconds(keyInfo.expirationTime),
59 | DateTimeOffset.FromUnixTimeMilliseconds(keyInfo.createdAt)
60 | )
61 | ) : new[] { new AccessTokenSigningKey(handshakeResponse.JwtSigningPublicKey,
62 | DateTimeOffset.FromUnixTimeMilliseconds(handshakeResponse.JwtSigningPublicKeyExpiryTime),
63 | now
64 | )};
65 |
66 | _handshake = new Handshake(
67 | jwtSigningPublicKeyList,
68 | handshakeResponse.AccessTokenBlacklistingEnabled,
69 | TimeSpan.FromMilliseconds(handshakeResponse.AccessTokenValidity),
70 | TimeSpan.FromMilliseconds(handshakeResponse.RefreshTokenValidity));
71 | }
72 | }
73 | catch (CoreApiResponseException e)
74 | {
75 | _logger.LogError(e, "Failed to get SuperTokens handshake");
76 | }
77 | catch (HttpRequestException e)
78 | {
79 | _logger.LogError(e, "Failed to get SuperTokens handshake");
80 | }
81 | catch (JsonException e)
82 | {
83 | _logger.LogError(e, "Failed to parse SuperTokens handshake");
84 | }
85 | }
86 |
87 | if (_handshake != null)
88 | {
89 | return _handshake;
90 | }
91 | else
92 | {
93 | throw new InvalidOperationException("No SuperTokens handshake is available");
94 | }
95 | }
96 | finally
97 | {
98 | _refreshLock.Release();
99 | }
100 | }
101 |
102 | public async Task OnHandshakeChanged(IEnumerable? jwtSigningPublicKeyList, string jwtSigningPublicKey, DateTimeOffset jwtSigningPublicKeyExpiration)
103 | {
104 | var handshake = _handshake;
105 | if (handshake == null)
106 | {
107 | return;
108 | }
109 |
110 | var now = _clock.UtcNow;
111 | var updatedSigningPublicKeyList = jwtSigningPublicKeyList != null
112 | ? jwtSigningPublicKeyList.Select(keyInfo =>
113 | new AccessTokenSigningKey(keyInfo.publicKey,
114 | DateTimeOffset.FromUnixTimeMilliseconds(keyInfo.expirationTime),
115 | DateTimeOffset.FromUnixTimeMilliseconds(keyInfo.createdAt)
116 | ))
117 | : new[] {
118 | new AccessTokenSigningKey(jwtSigningPublicKey,
119 | jwtSigningPublicKeyExpiration,
120 | now
121 | )};
122 |
123 | if (handshake.GetAccessTokenSigningPublicKeyList(now).SequenceEqual(updatedSigningPublicKeyList))
124 | {
125 | return;
126 | }
127 |
128 | await _refreshLock.WaitAsync().ConfigureAwait(false);
129 | try
130 | {
131 | if (_handshake != null && !handshake.GetAccessTokenSigningPublicKeyList(now).SequenceEqual(updatedSigningPublicKeyList))
132 | {
133 | _handshake = new Handshake(
134 | updatedSigningPublicKeyList,
135 | _handshake.AccessTokenBlacklistingEnabled,
136 | _handshake.AccessTokenLifetime,
137 | _handshake.RefreshTokenLifetime);
138 | }
139 | }
140 | finally
141 | {
142 | _refreshLock.Release();
143 | }
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/IApiVersionContainer.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 |
4 | namespace SuperTokens.AspNetCore
5 | {
6 | public interface IApiVersionContainer
7 | {
8 | ValueTask GetApiVersionAsync(string? apiKey);
9 |
10 | ValueTask GetApiVersionAsync(string? apiKey, CancellationToken cancellationToken);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/IHandshakeContainer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace SuperTokens.AspNetCore
7 | {
8 | public interface IHandshakeContainer
9 | {
10 | Task GetHandshakeAsync(string? apiKey, string? cdiVersion);
11 |
12 | Task GetHandshakeAsync(string? apiKey, string? cdiVersion, CancellationToken cancellationToken);
13 |
14 | Task OnHandshakeChanged(IEnumerable? jwtSigningPublicKeyList, string jwtSigningPublicKey, DateTimeOffset jwtSigningPublicKeyExpiration);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/ISessionAccessor.cs:
--------------------------------------------------------------------------------
1 | namespace SuperTokens.AspNetCore
2 | {
3 | /// Provides access to the current , if one is available.
4 | public interface ISessionAccessor
5 | {
6 | ///
7 | /// Gets or sets the current . Returns null if there is no active
8 | /// .
9 | ///
10 | public SuperTokensSession? Session { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/ISessionRecipe.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace SuperTokens.AspNetCore
4 | {
5 | public interface ISessionRecipe
6 | {
7 | Task AuthenticateAsync(string userId);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/JwtUtilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics.CodeAnalysis;
3 | using System.Security.Cryptography;
4 | using System.Text;
5 |
6 | namespace SuperTokens.AspNetCore
7 | {
8 | internal static class JwtUtilities
9 | {
10 | ///
11 | /// A base64 encoded representation of the following JWT header:
12 | ///
13 | ///{"alg":"RS256","typ":"JWT","version":"1"}
14 | ///
15 | ///
16 | private const string VersionOneHeader = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIxIn0=";
17 |
18 | ///
19 | /// A base64 encoded representation of the following JWT header:
20 | ///
21 | ///{"alg":"RS256","typ":"JWT","version":"2"}
22 | ///
23 | ///
24 | private const string VersionTwoHeader = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=";
25 |
26 | public static bool TryParse(string jwt, [NotNullWhen(true)] out string? jwtPayload, out string[]? components)
27 | {
28 | // Parse JWT.
29 | components = jwt.Split('.');
30 | if (components.Length != 3 || components[1].Length == 0)
31 | {
32 | jwtPayload = null;
33 | components = null;
34 | return false;
35 | }
36 |
37 | // Verify JWT header.
38 | if (!VersionOneHeader.Equals(components[0], StringComparison.Ordinal) && !VersionTwoHeader.Equals(components[0], StringComparison.Ordinal))
39 | {
40 | jwtPayload = null;
41 | components = null;
42 | return false;
43 | }
44 |
45 | // Verify JWT payload.
46 | var buffer = new Span(new byte[components[1].Length]);
47 | if (!Convert.TryFromBase64String(components[1], buffer, out var bufferLength))
48 | {
49 | jwtPayload = null;
50 | components = null;
51 | return false;
52 | }
53 |
54 | jwtPayload = Encoding.UTF8.GetString(buffer.Slice(0, bufferLength));
55 | return true;
56 | }
57 |
58 | public static bool TryParseAndValidate(string jwt, string jwtSigningPublicKey, [NotNullWhen(true)] out string? jwtPayload, out bool isSignatureValid)
59 | {
60 | // Parse JWT.
61 | var components = jwt.Split('.');
62 | if (components.Length != 3 || components[1].Length == 0)
63 | {
64 | jwtPayload = null;
65 | isSignatureValid = false;
66 | return false;
67 | }
68 |
69 | // Verify JWT header.
70 | if (!VersionOneHeader.Equals(components[0], StringComparison.Ordinal) && !VersionTwoHeader.Equals(components[0], StringComparison.Ordinal))
71 | {
72 | jwtPayload = null;
73 | isSignatureValid = false;
74 | return false;
75 | }
76 |
77 | // Verify JWT payload.
78 | var buffer = new Span(new byte[components[1].Length]);
79 | if (!Convert.TryFromBase64String(components[1], buffer, out var bufferLength))
80 | {
81 | jwtPayload = null;
82 | isSignatureValid = false;
83 | return false;
84 | }
85 |
86 | jwtPayload = Encoding.UTF8.GetString(buffer.Slice(0, bufferLength));
87 | isSignatureValid = Validate(components, jwtSigningPublicKey);
88 | return true;
89 | }
90 |
91 | public static bool Validate(string[] components, string jwtSigningPublicKey)
92 | {
93 | // Verify JWT signature.
94 | var rsa = RSA.Create();
95 | var key = Convert.FromBase64String(jwtSigningPublicKey);
96 | rsa.ImportSubjectPublicKeyInfo(key, out _);
97 |
98 | var data = Encoding.UTF8.GetBytes($"{components[0]}.{components[1]}");
99 | var signature = Convert.FromBase64String(components[2]);
100 | return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SessionAccessor.cs:
--------------------------------------------------------------------------------
1 | namespace SuperTokens.AspNetCore
2 | {
3 | /// Provides an implementation of .
4 | internal class SessionAccessor : ISessionAccessor
5 | {
6 | ///
7 | public SuperTokensSession? Session { get; set; }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SessionRecipe.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Text.Json;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Http;
6 | using Microsoft.Extensions.Options;
7 | using Microsoft.Extensions.Primitives;
8 | using Microsoft.Net.Http.Headers;
9 | using SuperTokens.Net;
10 | using SuperTokens.Net.SessionRecipe;
11 |
12 | namespace SuperTokens.AspNetCore
13 | {
14 | public class SessionRecipe : ISessionRecipe
15 | {
16 | private readonly IApiVersionContainer _apiVersionContainer;
17 |
18 | private readonly ICoreApiClient _coreApiClient;
19 |
20 | private readonly IHandshakeContainer _handshakeContainer;
21 |
22 | private readonly IHttpContextAccessor _httpContextAccessor;
23 |
24 | private readonly IOptionsMonitor _options;
25 |
26 | private readonly ISessionAccessor _sessionAccessor;
27 |
28 | public SessionRecipe(ICoreApiClient coreApiClient, IHandshakeContainer handshakeContainer, ISessionAccessor sessionAccessor, IHttpContextAccessor httpContextAccessor, IOptionsMonitor options, IApiVersionContainer apiVersionContainer)
29 | {
30 | _coreApiClient = coreApiClient ?? throw new ArgumentNullException(nameof(coreApiClient));
31 | _handshakeContainer = handshakeContainer ?? throw new ArgumentNullException(nameof(handshakeContainer));
32 | _sessionAccessor = sessionAccessor ?? throw new ArgumentNullException(nameof(sessionAccessor));
33 | _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
34 | _options = options ?? throw new ArgumentNullException(nameof(options));
35 | _apiVersionContainer = apiVersionContainer ?? throw new ArgumentNullException(nameof(apiVersionContainer));
36 | }
37 |
38 | public async Task AuthenticateAsync(string userId)
39 | {
40 | var options = _options.Get(SuperTokensDefaults.AuthenticationScheme);
41 |
42 | var document = JsonDocument.Parse("{}");
43 | var emptyObject = document.RootElement.Clone();
44 | document.Dispose();
45 |
46 | var cdiVersion = await _apiVersionContainer.GetApiVersionAsync(options.CoreApiKey);
47 | var result = await _coreApiClient.CreateSessionAsync(options.CoreApiKey, cdiVersion, new CreateSessionRequest
48 | {
49 | EnableAntiCsrf = options.AntiCsrfMode == SuperTokensAntiCsrfMode.ViaToken,
50 | UserDataInDatabase = emptyObject,
51 | UserDataInJwt = emptyObject,
52 | UserId = userId,
53 | });
54 | if (!"OK".Equals(result.Status, StringComparison.Ordinal))
55 | {
56 | throw new InvalidOperationException("Failed to login the user.");
57 | }
58 |
59 | await _handshakeContainer.OnHandshakeChanged(result.JwtSigningPublicKeyList, result.JwtSigningPublicKey, DateTimeOffset.FromUnixTimeMilliseconds(result.JwtSigningPublicKeyExpiryTime));
60 |
61 | var context = _httpContextAccessor.HttpContext ?? throw new InvalidOperationException("The session recipe only works in a HTTP context.");
62 | if (context.Response.HasStarted)
63 | {
64 | throw new InvalidOperationException("The session recipe cannot send cookies after the response has started.");
65 | }
66 |
67 | context.Response.Headers[HeaderNames.SetCookie] = StringValues.Concat(
68 | context.Response.Headers[HeaderNames.SetCookie],
69 | new StringValues(new[]
70 | {
71 | new SetCookieHeaderValue(SuperTokensDefaults.AccessTokenCookieName, result.AccessToken.Token)
72 | {
73 | Domain = options.CookieDomain,
74 | Expires = DateTimeOffset.FromUnixTimeMilliseconds(result.AccessToken.Expiry),
75 | HttpOnly = true,
76 | Path = "/",
77 | SameSite = (Microsoft.Net.Http.Headers.SameSiteMode)options.CookieSameSite,
78 | Secure = options.CookieSecure == CookieSecurePolicy.Always || (options.CookieSecure == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
79 | }.ToString(),
80 | new SetCookieHeaderValue(SuperTokensDefaults.RefreshTokenCookieName, result.RefreshToken.Token)
81 | {
82 | Domain = options.CookieDomain,
83 | Expires = DateTimeOffset.FromUnixTimeMilliseconds(result.RefreshToken.Expiry),
84 | HttpOnly = true,
85 | Path = new StringSegment(options.RefreshPath ?? "/"),
86 | SameSite = (Microsoft.Net.Http.Headers.SameSiteMode)options.CookieSameSite,
87 | Secure = options.CookieSecure == CookieSecurePolicy.Always || (options.CookieSecure == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
88 | }.ToString(),
89 | new SetCookieHeaderValue(SuperTokensDefaults.IdRefreshTokenCookieName, result.IdRefreshToken.Token)
90 | {
91 | Domain = options.CookieDomain,
92 | Expires = DateTimeOffset.FromUnixTimeMilliseconds(result.IdRefreshToken.Expiry),
93 | HttpOnly = true,
94 | Path = "/",
95 | SameSite = (Microsoft.Net.Http.Headers.SameSiteMode)options.CookieSameSite,
96 | Secure = options.CookieSecure == CookieSecurePolicy.Always || (options.CookieSecure == CookieSecurePolicy.SameAsRequest && context.Request.IsHttps),
97 | }.ToString(),
98 | }));
99 |
100 | context.Response.Headers[SuperTokensDefaults.FrontTokenHeaderKey] = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonSerializer.Serialize(new
101 | {
102 | uid = result.Session.UserId,
103 | ate = result.AccessToken.Expiry,
104 | up = result.Session.UserDataInJwt,
105 | })));
106 | context.Response.Headers[SuperTokensDefaults.IdRefreshTokenHeaderKey] = $"{result.IdRefreshToken.Token};{result.IdRefreshToken.Expiry:D}";
107 | context.Response.Headers[HeaderNames.AccessControlExposeHeaders] = StringValues.Concat(
108 | context.Response.Headers[HeaderNames.AccessControlExposeHeaders],
109 | new StringValues(new[]
110 | {
111 | SuperTokensDefaults.FrontTokenHeaderKey,
112 | SuperTokensDefaults.IdRefreshTokenHeaderKey
113 | }));
114 |
115 | if (result.AntiCsrfToken != null)
116 | {
117 | context.Response.Headers[SuperTokensDefaults.AntiCsrfHeaderKey] = result.AntiCsrfToken;
118 | context.Response.Headers[HeaderNames.AccessControlExposeHeaders] = StringValues.Concat(
119 | context.Response.Headers[HeaderNames.AccessControlExposeHeaders],
120 | SuperTokensDefaults.AntiCsrfHeaderKey);
121 | }
122 |
123 | var session = new SuperTokensSession(result.Session.Handle, result.Session.UserId, result.Session.UserDataInJwt.ToString()!);
124 | _sessionAccessor.Session = session;
125 | return session;
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SuperTokens.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | seniorquico
6 | Copyright © 2021 Kyle Dodson
7 | true
8 | true
9 | Provides ASP.NET Core authentication services for SuperTokens.
10 | MIT
11 | $(SourceRoot)/artifacts/$(Configuration)
12 | https://github.com/seniorquico/SuperTokens.AspNetCore
13 |
14 |
15 | SuperTokens
16 | true
17 | snupkg
18 | 1.0.5
19 |
20 |
21 |
22 | AllEnabledByDefault
23 | true
24 | strict
25 | true
26 | latest
27 | true
28 | $(NoWarn);CS1591
29 | enable
30 | Library
31 | net5.0
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SuperTokensAntiCsrfMode.cs:
--------------------------------------------------------------------------------
1 | namespace SuperTokens.AspNetCore
2 | {
3 | public enum SuperTokensAntiCsrfMode
4 | {
5 | None = 0,
6 |
7 | ViaCustomHeader,
8 |
9 | ViaToken,
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SuperTokensDefaults.cs:
--------------------------------------------------------------------------------
1 | namespace SuperTokens.AspNetCore
2 | {
3 | public static class SuperTokensDefaults
4 | {
5 | public const string AccessTokenCookieName = "sAccessToken";
6 |
7 | public const string AntiCsrfHeaderKey = "anti-csrf";
8 |
9 | public const string AuthenticationScheme = "SuperTokens";
10 |
11 | public const string FrontendDriverInterfaceHeaderKey = "fdi-version";
12 |
13 | public const string FrontTokenHeaderKey = "front-token";
14 |
15 | public const string IdRefreshTokenCookieName = "sIdRefreshToken";
16 |
17 | public const string IdRefreshTokenHeaderKey = "id-refresh-token";
18 |
19 | public const string RecipeIdHeaderKey = "rid";
20 |
21 | public const string RefreshTokenCookieName = "sRefreshToken";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/SuperTokens.AspNetCore/SuperTokensHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net.Http;
4 | using System.Net.Mime;
5 | using System.Security.Claims;
6 | using System.Security.Principal;
7 | using System.Text;
8 | using System.Text.Encodings.Web;
9 | using System.Text.Json;
10 | using System.Text.Json.Serialization;
11 | using System.Threading.Tasks;
12 | using Microsoft.AspNetCore.Authentication;
13 | using Microsoft.AspNetCore.Http;
14 | using Microsoft.Extensions.Logging;
15 | using Microsoft.Extensions.Options;
16 | using Microsoft.Extensions.Primitives;
17 | using Microsoft.Net.Http.Headers;
18 | using SuperTokens.AspNetCore.Events;
19 | using SuperTokens.Net;
20 | using SuperTokens.Net.Core;
21 | using SuperTokens.Net.SessionRecipe;
22 |
23 | namespace SuperTokens.AspNetCore
24 | {
25 | public class SuperTokensHandler : SignOutAuthenticationHandler, IAuthenticationRequestHandler
26 | {
27 | private readonly IApiVersionContainer _apiVersionContainer;
28 |
29 | private readonly ICoreApiClient _coreApiClient;
30 |
31 | private readonly IHandshakeContainer _handshakeContainer;
32 |
33 | private readonly ISessionAccessor _sessionAccessor;
34 |
35 | public SuperTokensHandler(
36 | ICoreApiClient coreApiClient,
37 | IHandshakeContainer handshakeContainer,
38 | IApiVersionContainer apiVersionContainer,
39 | ISessionAccessor sessionAccessor,
40 | IOptionsMonitor options,
41 | ILoggerFactory logger,
42 | UrlEncoder encoder,
43 | ISystemClock clock) :
44 | base(options, logger, encoder, clock)
45 | {
46 | _coreApiClient = coreApiClient ?? throw new ArgumentNullException(nameof(coreApiClient));
47 | _apiVersionContainer = apiVersionContainer ?? throw new ArgumentNullException(nameof(apiVersionContainer));
48 | _handshakeContainer = handshakeContainer ?? throw new ArgumentNullException(nameof(handshakeContainer));
49 | _sessionAccessor = sessionAccessor ?? throw new ArgumentNullException(nameof(sessionAccessor));
50 | }
51 |
52 | protected new SuperTokensEvents Events
53 | {
54 | get => (SuperTokensEvents)base.Events!;
55 | set => base.Events = value;
56 | }
57 |
58 | public Task HandleRequestAsync()
59 | {
60 | if (this.Options.RefreshPath.HasValue && this.Options.RefreshPath == this.Request.Path && HttpMethods.IsPost(this.Request.Method))
61 | {
62 | return this.HandleRefreshRequestAsync();
63 | }
64 | else if (this.Options.SignOutPath.HasValue && this.Options.SignOutPath == this.Request.Path && HttpMethods.IsPost(this.Request.Method))
65 | {
66 | return this.HandleSignOutRequestAsync();
67 | }
68 |
69 | return TaskUtilities.FalseTask;
70 | }
71 |
72 | protected override Task