├── .gitattributes
├── .gitignore
├── LICENSE.txt
├── README.md
├── artifacts
└── .gitkeep
├── global.json
├── install.ps1
├── pack.ps1
├── template
├── .template.config
│ └── template.json
├── BlazorWithIdentity.Client
│ ├── App.razor
│ ├── BlazorWithIdentity.Client.csproj
│ ├── Pages
│ │ ├── Counter.razor
│ │ ├── FetchData.razor
│ │ ├── Index.razor
│ │ ├── Login.razor
│ │ └── Register.razor
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Services
│ │ ├── Contracts
│ │ │ └── IAuthorizeApi.cs
│ │ └── Implementations
│ │ │ ├── AuthorizeApi.cs
│ │ │ └── IdentityAuthenticationStateProvider.cs
│ ├── Shared
│ │ ├── LoginLayout.razor
│ │ ├── MainLayout.razor
│ │ ├── MainLayout.razor.css
│ │ ├── NavMenu.razor
│ │ ├── NavMenu.razor.css
│ │ ├── RedirectToLogin.razor
│ │ └── SurveyPrompt.razor
│ ├── _Imports.razor
│ └── wwwroot
│ │ ├── css
│ │ ├── app.css
│ │ ├── bootstrap
│ │ │ ├── bootstrap.min.css
│ │ │ └── bootstrap.min.css.map
│ │ └── open-iconic
│ │ │ ├── FONT-LICENSE
│ │ │ ├── ICON-LICENSE
│ │ │ ├── README.md
│ │ │ └── font
│ │ │ ├── css
│ │ │ └── open-iconic-bootstrap.min.css
│ │ │ └── fonts
│ │ │ ├── open-iconic.eot
│ │ │ ├── open-iconic.otf
│ │ │ ├── open-iconic.svg
│ │ │ ├── open-iconic.ttf
│ │ │ └── open-iconic.woff
│ │ ├── favicon.png
│ │ ├── icon-192.png
│ │ └── index.html
├── BlazorWithIdentity.Server
│ ├── BlazorWithIdentity.Server.csproj
│ ├── Controllers
│ │ ├── AuthorizeController.cs
│ │ └── SampleDataController.cs
│ ├── Data
│ │ └── ApplicationDbContext.cs
│ ├── Migrations
│ │ ├── 20190502083628_Init.Designer.cs
│ │ ├── 20190502083628_Init.cs
│ │ └── ApplicationDbContextModelSnapshot.cs
│ ├── Models
│ │ └── ApplicationUser.cs
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── appsettings.Development.json
│ └── appsettings.json
├── BlazorWithIdentity.Shared
│ ├── BlazorWithIdentity.Shared.csproj
│ ├── LoginParameters.cs
│ ├── RegisterParameters.cs
│ ├── UserInfo.cs
│ └── WeatherForecast.cs
└── BlazorWithIdentity.sln
├── templatepack.csproj
└── uninstall.ps1
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Dd]ebugPublic/
19 | [Rr]elease/
20 | [Rr]eleases/
21 | x64/
22 | x86/
23 | [Aa][Rr][Mm]/
24 | [Aa][Rr][Mm]64/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 | [Ll]og/
29 |
30 | # Visual Studio 2015/2017 cache/options directory
31 | .vs/
32 | # Uncomment if you have tasks that create the project's static files in wwwroot
33 | #wwwroot/
34 |
35 | # Visual Studio 2017 auto generated files
36 | Generated\ Files/
37 |
38 | # MSTest test Results
39 | [Tt]est[Rr]esult*/
40 | [Bb]uild[Ll]og.*
41 |
42 | # NUNIT
43 | *.VisualState.xml
44 | TestResult.xml
45 |
46 | # Build Results of an ATL Project
47 | [Dd]ebugPS/
48 | [Rr]eleasePS/
49 | dlldata.c
50 |
51 | # Benchmark Results
52 | BenchmarkDotNet.Artifacts/
53 |
54 | # .NET Core
55 | project.lock.json
56 | project.fragment.lock.json
57 |
58 | # StyleCop
59 | StyleCopReport.xml
60 |
61 | # Files built by Visual Studio
62 | *_i.c
63 | *_p.c
64 | *_h.h
65 | *.ilk
66 | *.meta
67 | *.obj
68 | *.iobj
69 | *.pch
70 | *.pdb
71 | *.ipdb
72 | *.pgc
73 | *.pgd
74 | *.rsp
75 | *.sbr
76 | *.tlb
77 | *.tli
78 | *.tlh
79 | *.tmp
80 | *.tmp_proj
81 | *_wpftmp.csproj
82 | *.log
83 | *.vspscc
84 | *.vssscc
85 | .builds
86 | *.pidb
87 | *.svclog
88 | *.scc
89 |
90 | # Chutzpah Test files
91 | _Chutzpah*
92 |
93 | # Visual C++ cache files
94 | ipch/
95 | *.aps
96 | *.ncb
97 | *.opendb
98 | *.opensdf
99 | *.sdf
100 | *.cachefile
101 | *.VC.db
102 | *.VC.VC.opendb
103 |
104 | # Visual Studio profiler
105 | *.psess
106 | *.vsp
107 | *.vspx
108 | *.sap
109 |
110 | # Visual Studio Trace Files
111 | *.e2e
112 |
113 | # TFS 2012 Local Workspace
114 | $tf/
115 |
116 | # Guidance Automation Toolkit
117 | *.gpState
118 |
119 | # ReSharper is a .NET coding add-in
120 | _ReSharper*/
121 | *.[Rr]e[Ss]harper
122 | *.DotSettings.user
123 |
124 | # JustCode is a .NET coding add-in
125 | .JustCode
126 |
127 | # TeamCity is a build add-in
128 | _TeamCity*
129 |
130 | # DotCover is a Code Coverage Tool
131 | *.dotCover
132 |
133 | # AxoCover is a Code Coverage Tool
134 | .axoCover/*
135 | !.axoCover/settings.json
136 |
137 | # Visual Studio code coverage results
138 | *.coverage
139 | *.coveragexml
140 |
141 | # NCrunch
142 | _NCrunch_*
143 | .*crunch*.local.xml
144 | nCrunchTemp_*
145 |
146 | # MightyMoose
147 | *.mm.*
148 | AutoTest.Net/
149 |
150 | # Web workbench (sass)
151 | .sass-cache/
152 |
153 | # Installshield output folder
154 | [Ee]xpress/
155 |
156 | # DocProject is a documentation generator add-in
157 | DocProject/buildhelp/
158 | DocProject/Help/*.HxT
159 | DocProject/Help/*.HxC
160 | DocProject/Help/*.hhc
161 | DocProject/Help/*.hhk
162 | DocProject/Help/*.hhp
163 | DocProject/Help/Html2
164 | DocProject/Help/html
165 |
166 | # Click-Once directory
167 | publish/
168 |
169 | # Publish Web Output
170 | *.[Pp]ublish.xml
171 | *.azurePubxml
172 | # Note: Comment the next line if you want to checkin your web deploy settings,
173 | # but database connection strings (with potential passwords) will be unencrypted
174 | *.pubxml
175 | *.publishproj
176 |
177 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
178 | # checkin your Azure Web App publish settings, but sensitive information contained
179 | # in these scripts will be unencrypted
180 | PublishScripts/
181 |
182 | # NuGet Packages
183 | *.nupkg
184 | # The packages folder can be ignored because of Package Restore
185 | **/[Pp]ackages/*
186 | # except build/, which is used as an MSBuild target.
187 | !**/[Pp]ackages/build/
188 | # Uncomment if necessary however generally it will be regenerated when needed
189 | #!**/[Pp]ackages/repositories.config
190 | # NuGet v3's project.json files produces more ignorable files
191 | *.nuget.props
192 | *.nuget.targets
193 |
194 | # Microsoft Azure Build Output
195 | csx/
196 | *.build.csdef
197 |
198 | # Microsoft Azure Emulator
199 | ecf/
200 | rcf/
201 |
202 | # Windows Store app package directories and files
203 | AppPackages/
204 | BundleArtifacts/
205 | Package.StoreAssociation.xml
206 | _pkginfo.txt
207 | *.appx
208 |
209 | # Visual Studio cache files
210 | # files ending in .cache can be ignored
211 | *.[Cc]ache
212 | # but keep track of directories ending in .cache
213 | !?*.[Cc]ache/
214 |
215 | # Others
216 | ClientBin/
217 | ~$*
218 | *~
219 | *.dbmdl
220 | *.dbproj.schemaview
221 | *.jfm
222 | *.pfx
223 | *.publishsettings
224 | orleans.codegen.cs
225 |
226 | # Including strong name files can present a security risk
227 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
228 | #*.snk
229 |
230 | # Since there are multiple workflows, uncomment next line to ignore bower_components
231 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
232 | #bower_components/
233 |
234 | # RIA/Silverlight projects
235 | Generated_Code/
236 |
237 | # Backup & report files from converting an old project file
238 | # to a newer Visual Studio version. Backup files are not needed,
239 | # because we have git ;-)
240 | _UpgradeReport_Files/
241 | Backup*/
242 | UpgradeLog*.XML
243 | UpgradeLog*.htm
244 | ServiceFabricBackup/
245 | *.rptproj.bak
246 |
247 | # SQL Server files
248 | *.mdf
249 | *.ldf
250 | *.ndf
251 |
252 | # Business Intelligence projects
253 | *.rdl.data
254 | *.bim.layout
255 | *.bim_*.settings
256 | *.rptproj.rsuser
257 | *- Backup*.rdl
258 |
259 | # Microsoft Fakes
260 | FakesAssemblies/
261 |
262 | # GhostDoc plugin setting file
263 | *.GhostDoc.xml
264 |
265 | # Node.js Tools for Visual Studio
266 | .ntvs_analysis.dat
267 | node_modules/
268 |
269 | # Visual Studio 6 build log
270 | *.plg
271 |
272 | # Visual Studio 6 workspace options file
273 | *.opt
274 |
275 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
276 | *.vbw
277 |
278 | # Visual Studio LightSwitch build output
279 | **/*.HTMLClient/GeneratedArtifacts
280 | **/*.DesktopClient/GeneratedArtifacts
281 | **/*.DesktopClient/ModelManifest.xml
282 | **/*.Server/GeneratedArtifacts
283 | **/*.Server/ModelManifest.xml
284 | _Pvt_Extensions
285 |
286 | # Paket dependency manager
287 | .paket/paket.exe
288 | paket-files/
289 |
290 | # FAKE - F# Make
291 | .fake/
292 |
293 | # JetBrains Rider
294 | .idea/
295 | *.sln.iml
296 |
297 | # CodeRush personal settings
298 | .cr/personal
299 |
300 | # Python Tools for Visual Studio (PTVS)
301 | __pycache__/
302 | *.pyc
303 |
304 | # Cake - Uncomment if you are using it
305 | # tools/**
306 | # !tools/packages.config
307 |
308 | # Tabs Studio
309 | *.tss
310 |
311 | # Telerik's JustMock configuration file
312 | *.jmconfig
313 |
314 | # BizTalk build output
315 | *.btp.cs
316 | *.btm.cs
317 | *.odx.cs
318 | *.xsd.cs
319 |
320 | # OpenCover UI analysis results
321 | OpenCover/
322 |
323 | # Azure Stream Analytics local run output
324 | ASALocalRun/
325 |
326 | # MSBuild Binary and Structured Log
327 | *.binlog
328 |
329 | # NVidia Nsight GPU debugger configuration file
330 | *.nvuser
331 |
332 | # MFractors (Xamarin productivity tool) working folder
333 | .mfractor/
334 |
335 | # Local History for Visual Studio
336 | .localhistory/
337 |
338 | # BeatPulse healthcheck temp database
339 | healthchecksdb
340 | **/data.db
341 | /template/BlazorWithIdentity.Server/data.db-shm
342 | /template/BlazorWithIdentity.Server/data.db-wal
343 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 stavroskasidis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Blazor with Identity
2 |
3 | [](https://dev.azure.com/stavros-kasidis/Blazor%20With%20Identity/_build/latest?definitionId=18) [](https://www.nuget.org/packages/BlazorWithIdentity.Template) [](https://www.nuget.org/packages/BlazorWithIdentity.Template) [](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7CRGWPYB5AKJQ¤cy_code=EUR&source=url)
4 |
5 |
6 | A project template for a blazor wasm hosted app using cookie based authentication with ef core identity
7 |
8 | ## Using the template
9 | 1. Install the template
10 | ```
11 | dotnet new --install BlazorWithIdentity.Template
12 | ```
13 | 2. Create a new project
14 | ```
15 | dotnet new blazorwithidentity -o MyBlazorApp
16 | ```
17 |
18 | ## How to run
19 | 1. Install [**the latest dotnet sdk**](https://dotnet.microsoft.com/download) and the latest [**Visual Studio**](https://visualstudio.microsoft.com/vs/).
20 | 2. Clone or download.
21 | 3. Open the solution in the template folder and press F5.
22 | 4. Create a user using the `Create Account` button in the login page or login if you have already created a user.
23 |
24 | ## Live demo
25 | https://blazorwithidentity.azurewebsites.net/
26 |
--------------------------------------------------------------------------------
/artifacts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/artifacts/.gitkeep
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "7.0.100"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/install.ps1:
--------------------------------------------------------------------------------
1 | dotnet new -u BlazorWithIdentity.Template
2 | dotnet new -i artifacts\BlazorWithIdentity.Template.*
--------------------------------------------------------------------------------
/pack.ps1:
--------------------------------------------------------------------------------
1 | param(
2 | [string] $VersionSuffix
3 | )
4 | Push-Location $PSScriptRoot
5 |
6 | function Write-Message{
7 | param([string]$message)
8 | Write-Host
9 | Write-Host $message
10 | Write-Host
11 | }
12 | function Confirm-PreviousCommand {
13 | param([string]$errorMessage)
14 | if ( $LASTEXITCODE -ne 0) {
15 | if( $errorMessage) {
16 | Write-Message $errorMessage
17 | }
18 | exit $LASTEXITCODE
19 | }
20 | }
21 |
22 | function Confirm-Process {
23 | param ([System.Diagnostics.Process]$process,[string]$errorMessage)
24 | $process.WaitForExit()
25 | if($process.ExitCode -ne 0){
26 | Write-Host $process.ExitCode
27 | if( $errorMessage) {
28 | Write-Message $errorMessage
29 | }
30 | exit $process.ExitCode
31 | }
32 | }
33 |
34 | Write-Host "Parameters"
35 | Write-Host "=========="
36 | Write-Host "Version suffix: $VersionSuffix"
37 |
38 | # Check prerequisites
39 | $proc = Start-Process "dotnet" -ArgumentList "--version" -PassThru
40 | Confirm-Process $proc "Could not find dotnet sdk, please install and run again ..."
41 |
42 | Write-Message "Cleaning artifacts folder"
43 | Remove-Item -Path artifacts/*.nupkg -Recurse
44 |
45 | Write-Message "Packing ..."
46 | dotnet pack templatepack.csproj -c Release -o artifacts /p:VersionSuffix="$VersionSuffix"
47 | Confirm-PreviousCommand
48 |
49 | Write-Message "Pack completed successfully"
--------------------------------------------------------------------------------
/template/.template.config/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/template",
3 | "author": "Stavros Kasidis (AkiraGTX)",
4 | "name": "Blazor With Identity",
5 | "identity": "blazor.withidentity",
6 | "groupIdentity":"blazor",
7 | "shortName": "blazorwithidentity",
8 | "classifications": [ "Web", "Blazor", "WebAssembly" ],
9 | "tags": {
10 | "language": "C#",
11 | "type":"project"
12 | },
13 | "sourceName": "BlazorWithIdentity",
14 | "preferNameDirectory": true
15 | }
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/App.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @if (context.User.Identity?.IsAuthenticated != true)
7 | {
8 |
9 | }
10 | else
11 | {
12 | You are not authorized to access this resource.
13 | }
14 |
15 |
16 |
17 |
18 |
19 | Not found
20 |
21 | Sorry, there's nothing at this address.
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/BlazorWithIdentity.Client.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net7.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Pages/Counter.razor:
--------------------------------------------------------------------------------
1 | @page "/counter"
2 | @attribute [Authorize]
3 |
4 | Counter
5 |
6 |
Counter
7 |
8 | Current count: @currentCount
9 |
10 | Click me
11 |
12 | @code {
13 | private int currentCount = 0;
14 |
15 | private void IncrementCount()
16 | {
17 | currentCount++;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Pages/FetchData.razor:
--------------------------------------------------------------------------------
1 | @page "/fetchdata"
2 | @attribute [Authorize]
3 | @using BlazorWithIdentity.Shared
4 | @inject HttpClient Http
5 |
6 | Weather forecast
7 |
8 | Weather forecast
9 |
10 | This component demonstrates fetching data from the server.
11 |
12 | @if (forecasts == null)
13 | {
14 | Loading...
15 | }
16 | else
17 | {
18 |
19 |
20 |
21 | Date
22 | Temp. (C)
23 | Temp. (F)
24 | Summary
25 |
26 |
27 |
28 | @foreach (var forecast in forecasts)
29 | {
30 |
31 | @forecast.Date.ToShortDateString()
32 | @forecast.TemperatureC
33 | @forecast.TemperatureF
34 | @forecast.Summary
35 |
36 | }
37 |
38 |
39 | }
40 |
41 | @code {
42 | private WeatherForecast[]? forecasts;
43 |
44 | protected override async Task OnInitializedAsync()
45 | {
46 | forecasts = await Http.GetFromJsonAsync("api/SampleData/WeatherForecasts");
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Pages/Index.razor:
--------------------------------------------------------------------------------
1 | @page "/"
2 | @attribute [Authorize]
3 |
4 | Index
5 |
6 |
7 |
8 | Hello @context.User.Identity.Name !!
9 |
10 | Welcome to your new app.
11 |
12 |
13 |
14 |
15 | Loading ...
16 |
17 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Pages/Login.razor:
--------------------------------------------------------------------------------
1 | @page "/login"
2 | @layout LoginLayout
3 | @inject NavigationManager navigationManager
4 | @inject IdentityAuthenticationStateProvider authStateProvider
5 |
6 | Login
7 |
8 |
9 | Blazor with Identity Sample
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | User Name
26 |
27 |
28 |
29 |
30 |
31 | Password
32 |
33 |
34 |
35 |
41 |
42 |
43 | Sign in
44 |
45 |
46 | @error
47 |
48 |
49 | Create account
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | @code {
59 | LoginParameters loginParameters { get; set; } = new LoginParameters();
60 | string error { get; set; }
61 |
62 | async Task OnSubmit()
63 | {
64 | error = null;
65 | try
66 | {
67 | await authStateProvider.Login(loginParameters);
68 | navigationManager.NavigateTo("");
69 | }
70 | catch (Exception ex)
71 | {
72 | error = ex.Message;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Pages/Register.razor:
--------------------------------------------------------------------------------
1 | @page "/register"
2 | @layout LoginLayout
3 | @inject NavigationManager navigationManager
4 | @inject IdentityAuthenticationStateProvider authStateProvider
5 |
6 | Register
7 |
8 |
9 | Blazor with Identity Sample
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | User Name
26 |
27 |
28 |
29 |
30 |
31 | Password
32 |
33 |
34 |
35 |
36 |
37 | Password Confirmation
38 |
39 |
40 |
41 |
42 | Create account
43 |
44 |
45 | @error
46 |
47 |
48 | Already have an account? Click here to login
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | @code {
58 |
59 | RegisterParameters registerParameters { get; set; } = new RegisterParameters();
60 | string error { get; set; }
61 |
62 | async Task OnSubmit()
63 | {
64 | error = null;
65 | try
66 | {
67 | await authStateProvider.Register(registerParameters);
68 | navigationManager.NavigateTo("");
69 | }
70 | catch (Exception ex)
71 | {
72 | error = ex.Message;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Program.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Client;
2 | using BlazorWithIdentity.Client.Services.Contracts;
3 | using BlazorWithIdentity.Client.Services.Implementations;
4 | using BlazorWithIdentity.Client.States;
5 | using Microsoft.AspNetCore.Components.Web;
6 | using Microsoft.AspNetCore.Components.Authorization;
7 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
8 |
9 | var builder = WebAssemblyHostBuilder.CreateDefault(args);
10 | builder.RootComponents.Add("#app");
11 | builder.RootComponents.Add("head::after");
12 |
13 | builder.Services.AddOptions();
14 | builder.Services.AddAuthorizationCore();
15 | builder.Services.AddScoped();
16 | builder.Services.AddScoped(s => s.GetRequiredService());
17 | builder.Services.AddScoped();
18 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
19 |
20 | await builder.Build().RunAsync();
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:53415",
7 | "sslPort": 44370
8 | }
9 | },
10 | "profiles": {
11 | "BlazorWithIdentity": {
12 | "commandName": "Project",
13 | "dotnetRunMessages": "true",
14 | "launchBrowser": true,
15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
16 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
17 | "environmentVariables": {
18 | "ASPNETCORE_ENVIRONMENT": "Development"
19 | }
20 | },
21 | "IIS Express": {
22 | "commandName": "IISExpress",
23 | "launchBrowser": true,
24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Services/Contracts/IAuthorizeApi.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Shared;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace BlazorWithIdentity.Client.Services.Contracts
8 | {
9 | public interface IAuthorizeApi
10 | {
11 | Task Login(LoginParameters loginParameters);
12 | Task Register(RegisterParameters registerParameters);
13 | Task Logout();
14 | Task GetUserInfo();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Services/Implementations/AuthorizeApi.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Client.Services.Contracts;
2 | using BlazorWithIdentity.Shared;
3 | using Microsoft.AspNetCore.Components;
4 | using Microsoft.JSInterop;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Net.Http;
9 | using System.Net.Http.Json;
10 | using System.Text;
11 | using System.Text.Json;
12 | using System.Text.Json.Serialization;
13 | using System.Threading.Tasks;
14 |
15 | namespace BlazorWithIdentity.Client.Services.Implementations
16 | {
17 | public class AuthorizeApi : IAuthorizeApi
18 | {
19 | private readonly HttpClient _httpClient;
20 |
21 | public AuthorizeApi(HttpClient httpClient)
22 | {
23 | _httpClient = httpClient;
24 | }
25 |
26 | public async Task Login(LoginParameters loginParameters)
27 | {
28 | //var stringContent = new StringContent(JsonSerializer.Serialize(loginParameters), Encoding.UTF8, "application/json");
29 | var result = await _httpClient.PostAsJsonAsync("api/Authorize/Login", loginParameters);
30 | if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync());
31 | result.EnsureSuccessStatusCode();
32 | }
33 |
34 | public async Task Logout()
35 | {
36 | var result = await _httpClient.PostAsync("api/Authorize/Logout", null);
37 | result.EnsureSuccessStatusCode();
38 | }
39 |
40 | public async Task Register(RegisterParameters registerParameters)
41 | {
42 | //var stringContent = new StringContent(JsonSerializer.Serialize(registerParameters), Encoding.UTF8, "application/json");
43 | var result = await _httpClient.PostAsJsonAsync("api/Authorize/Register", registerParameters);
44 | if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync());
45 | result.EnsureSuccessStatusCode();
46 | }
47 |
48 | public async Task GetUserInfo()
49 | {
50 | var result = await _httpClient.GetFromJsonAsync("api/Authorize/UserInfo");
51 | return result;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Services/Implementations/IdentityAuthenticationStateProvider.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Client.Services.Contracts;
2 | using BlazorWithIdentity.Shared;
3 | using Microsoft.AspNetCore.Components;
4 | using Microsoft.AspNetCore.Components.Authorization;
5 | using Microsoft.JSInterop;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Net;
10 | using System.Net.Http;
11 | using System.Security.Claims;
12 | using System.Threading.Tasks;
13 |
14 | namespace BlazorWithIdentity.Client.States
15 | {
16 | public class IdentityAuthenticationStateProvider : AuthenticationStateProvider
17 | {
18 | private UserInfo _userInfoCache;
19 | private readonly IAuthorizeApi _authorizeApi;
20 |
21 | public IdentityAuthenticationStateProvider(IAuthorizeApi authorizeApi)
22 | {
23 | this._authorizeApi = authorizeApi;
24 | }
25 |
26 | public async Task Login(LoginParameters loginParameters)
27 | {
28 | await _authorizeApi.Login(loginParameters);
29 | NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
30 | }
31 |
32 | public async Task Register(RegisterParameters registerParameters)
33 | {
34 | await _authorizeApi.Register(registerParameters);
35 | NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
36 | }
37 |
38 | public async Task Logout()
39 | {
40 | await _authorizeApi.Logout();
41 | _userInfoCache = null;
42 | NotifyAuthenticationStateChanged(GetAuthenticationStateAsync());
43 | }
44 |
45 | private async Task GetUserInfo()
46 | {
47 | if (_userInfoCache != null && _userInfoCache.IsAuthenticated) return _userInfoCache;
48 | _userInfoCache = await _authorizeApi.GetUserInfo();
49 | return _userInfoCache;
50 | }
51 |
52 | public override async Task GetAuthenticationStateAsync()
53 | {
54 | var identity = new ClaimsIdentity();
55 | try
56 | {
57 | var userInfo = await GetUserInfo();
58 | if (userInfo.IsAuthenticated)
59 | {
60 | var claims = new[] { new Claim(ClaimTypes.Name, userInfo.UserName) }.Concat(userInfo.ExposedClaims.Select(c => new Claim(c.Key, c.Value)));
61 | identity = new ClaimsIdentity(claims, "Server authentication");
62 | }
63 | }
64 | catch (HttpRequestException ex)
65 | {
66 | Console.WriteLine("Request failed:" + ex.ToString());
67 | }
68 |
69 | return new AuthenticationState(new ClaimsPrincipal(identity));
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/LoginLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 |
3 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/MainLayout.razor:
--------------------------------------------------------------------------------
1 | @inherits LayoutComponentBase
2 | @inject NavigationManager navigationManager
3 | @inject IdentityAuthenticationStateProvider authStateProvider
4 |
5 |
6 |
7 | @*Show the menu and the rest of the body*@
8 |
11 |
12 |
13 |
14 | Logout
15 |
16 |
17 |
18 | @Body
19 |
20 |
21 |
22 |
23 | @*Just render the body so that RedirectToLogin works*@
24 | @Body
25 |
26 |
27 |
28 |
29 |
30 | @code {
31 |
32 | async Task LogoutClick()
33 | {
34 | await authStateProvider.Logout();
35 | navigationManager.NavigateTo("/login");
36 | }
37 | }
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/MainLayout.razor.css:
--------------------------------------------------------------------------------
1 | .page {
2 | position: relative;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 |
7 | main {
8 | flex: 1;
9 | }
10 |
11 | .sidebar {
12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
13 | }
14 |
15 | .top-row {
16 | background-color: #f7f7f7;
17 | border-bottom: 1px solid #d6d5d5;
18 | justify-content: flex-end;
19 | height: 3.5rem;
20 | display: flex;
21 | align-items: center;
22 | }
23 |
24 | .top-row ::deep a, .top-row ::deep .btn-link {
25 | white-space: nowrap;
26 | margin-left: 1.5rem;
27 | text-decoration: none;
28 | }
29 |
30 | .top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
31 | text-decoration: underline;
32 | }
33 |
34 | .top-row ::deep a:first-child {
35 | overflow: hidden;
36 | text-overflow: ellipsis;
37 | }
38 |
39 | @media (max-width: 640.98px) {
40 | .top-row:not(.auth) {
41 | display: none;
42 | }
43 |
44 | .top-row.auth {
45 | justify-content: space-between;
46 | }
47 |
48 | .top-row ::deep a, .top-row ::deep .btn-link {
49 | margin-left: 0;
50 | }
51 | }
52 |
53 | @media (min-width: 641px) {
54 | .page {
55 | flex-direction: row;
56 | }
57 |
58 | .sidebar {
59 | width: 250px;
60 | height: 100vh;
61 | position: sticky;
62 | top: 0;
63 | }
64 |
65 | .top-row {
66 | position: sticky;
67 | top: 0;
68 | z-index: 1;
69 | }
70 |
71 | .top-row.auth ::deep a:first-child {
72 | flex: 1;
73 | text-align: right;
74 | width: 0;
75 | }
76 |
77 | .top-row, article {
78 | padding-left: 2rem !important;
79 | padding-right: 1.5rem !important;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/NavMenu.razor:
--------------------------------------------------------------------------------
1 |
9 |
10 |
29 |
30 | @code {
31 | private bool collapseNavMenu = true;
32 |
33 | private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
34 |
35 | private void ToggleNavMenu()
36 | {
37 | collapseNavMenu = !collapseNavMenu;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/NavMenu.razor.css:
--------------------------------------------------------------------------------
1 | .navbar-toggler {
2 | background-color: rgba(255, 255, 255, 0.1);
3 | }
4 |
5 | .top-row {
6 | height: 3.5rem;
7 | background-color: rgba(0,0,0,0.4);
8 | }
9 |
10 | .navbar-brand {
11 | font-size: 1.1rem;
12 | }
13 |
14 | .oi {
15 | width: 2rem;
16 | font-size: 1.1rem;
17 | vertical-align: text-top;
18 | top: -2px;
19 | }
20 |
21 | .nav-item {
22 | font-size: 0.9rem;
23 | padding-bottom: 0.5rem;
24 | }
25 |
26 | .nav-item:first-of-type {
27 | padding-top: 1rem;
28 | }
29 |
30 | .nav-item:last-of-type {
31 | padding-bottom: 1rem;
32 | }
33 |
34 | .nav-item ::deep a {
35 | color: #d7d7d7;
36 | border-radius: 4px;
37 | height: 3rem;
38 | display: flex;
39 | align-items: center;
40 | line-height: 3rem;
41 | }
42 |
43 | .nav-item ::deep a.active {
44 | background-color: rgba(255,255,255,0.25);
45 | color: white;
46 | }
47 |
48 | .nav-item ::deep a:hover {
49 | background-color: rgba(255,255,255,0.1);
50 | color: white;
51 | }
52 |
53 | @media (min-width: 641px) {
54 | .navbar-toggler {
55 | display: none;
56 | }
57 |
58 | .collapse {
59 | /* Never collapse the sidebar for wide screens */
60 | display: block;
61 | }
62 |
63 | .nav-scrollable {
64 | /* Allow sidebar to scroll for tall menus */
65 | height: calc(100vh - 3.5rem);
66 | overflow-y: auto;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/RedirectToLogin.razor:
--------------------------------------------------------------------------------
1 | @inject NavigationManager navigationManager
2 | Redirecting...
3 | @code{
4 |
5 | protected override void OnInitialized()
6 | {
7 | navigationManager.NavigateTo("/login");
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/Shared/SurveyPrompt.razor:
--------------------------------------------------------------------------------
1 |
2 |
3 |
@Title
4 |
5 |
6 | Please take our
7 | brief survey
8 |
9 | and tell us what you think.
10 |
11 |
12 | @code {
13 | // Demonstrates how a parent component can supply parameters
14 | [Parameter]
15 | public string? Title { get; set; }
16 | }
17 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/_Imports.razor:
--------------------------------------------------------------------------------
1 | @using System.Net.Http
2 | @using Microsoft.AspNetCore.Components.Forms
3 | @using Microsoft.AspNetCore.Components.Routing
4 | @using Microsoft.AspNetCore.Components.Web
5 | @using Microsoft.AspNetCore.Authorization.Infrastructure
6 | @using Microsoft.AspNetCore.Components.Authorization
7 | @using Microsoft.AspNetCore.Authorization
8 | @using Microsoft.JSInterop
9 | @using BlazorWithIdentity.Shared
10 | @using BlazorWithIdentity.Client
11 | @using BlazorWithIdentity.Client.Shared
12 | @using BlazorWithIdentity.Client.Services.Contracts
13 | @using BlazorWithIdentity.Client.Services.Implementations
14 | @using BlazorWithIdentity.Client.States
15 | @using System.Security.Claims
16 | @using System.Net.Http.Json
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/app.css:
--------------------------------------------------------------------------------
1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
2 |
3 | html, body {
4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
5 | }
6 |
7 | h1:focus {
8 | outline: none;
9 | }
10 |
11 | a, .btn-link {
12 | color: #0071c1;
13 | }
14 |
15 | .btn-primary {
16 | color: #fff;
17 | background-color: #1b6ec2;
18 | border-color: #1861ac;
19 | }
20 |
21 | .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
22 | box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
23 | }
24 |
25 | .content {
26 | padding-top: 1.1rem;
27 | }
28 |
29 | .valid.modified:not([type=checkbox]) {
30 | outline: 1px solid #26b050;
31 | }
32 |
33 | .invalid {
34 | outline: 1px solid red;
35 | }
36 |
37 | .validation-message {
38 | color: red;
39 | }
40 |
41 | #blazor-error-ui {
42 | background: lightyellow;
43 | bottom: 0;
44 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
45 | display: none;
46 | left: 0;
47 | padding: 0.6rem 1.25rem 0.7rem 1.25rem;
48 | position: fixed;
49 | width: 100%;
50 | z-index: 1000;
51 | }
52 |
53 | #blazor-error-ui .dismiss {
54 | cursor: pointer;
55 | position: absolute;
56 | right: 0.75rem;
57 | top: 0.5rem;
58 | }
59 |
60 | .blazor-error-boundary {
61 | background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
62 | padding: 1rem 1rem 1rem 3.7rem;
63 | color: white;
64 | }
65 |
66 | .blazor-error-boundary::after {
67 | content: "An error has occurred."
68 | }
69 |
70 | .loading-progress {
71 | position: relative;
72 | display: block;
73 | width: 8rem;
74 | height: 8rem;
75 | margin: 20vh auto 1rem auto;
76 | }
77 |
78 | .loading-progress circle {
79 | fill: none;
80 | stroke: #e0e0e0;
81 | stroke-width: 0.6rem;
82 | transform-origin: 50% 50%;
83 | transform: rotate(-90deg);
84 | }
85 |
86 | .loading-progress circle:last-child {
87 | stroke: #1b6ec2;
88 | stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
89 | transition: stroke-dasharray 0.05s ease-in-out;
90 | }
91 |
92 | .loading-progress-text {
93 | position: absolute;
94 | text-align: center;
95 | font-weight: bold;
96 | inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
97 | }
98 |
99 | .loading-progress-text:after {
100 | content: var(--blazor-load-percentage-text, "Loading");
101 | }
102 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/FONT-LICENSE:
--------------------------------------------------------------------------------
1 | SIL OPEN FONT LICENSE Version 1.1
2 |
3 | Copyright (c) 2014 Waybury
4 |
5 | PREAMBLE
6 | The goals of the Open Font License (OFL) are to stimulate worldwide
7 | development of collaborative font projects, to support the font creation
8 | efforts of academic and linguistic communities, and to provide a free and
9 | open framework in which fonts may be shared and improved in partnership
10 | with others.
11 |
12 | The OFL allows the licensed fonts to be used, studied, modified and
13 | redistributed freely as long as they are not sold by themselves. The
14 | fonts, including any derivative works, can be bundled, embedded,
15 | redistributed and/or sold with any software provided that any reserved
16 | names are not used by derivative works. The fonts and derivatives,
17 | however, cannot be released under any other type of license. The
18 | requirement for fonts to remain under this license does not apply
19 | to any document created using the fonts or their derivatives.
20 |
21 | DEFINITIONS
22 | "Font Software" refers to the set of files released by the Copyright
23 | Holder(s) under this license and clearly marked as such. This may
24 | include source files, build scripts and documentation.
25 |
26 | "Reserved Font Name" refers to any names specified as such after the
27 | copyright statement(s).
28 |
29 | "Original Version" refers to the collection of Font Software components as
30 | distributed by the Copyright Holder(s).
31 |
32 | "Modified Version" refers to any derivative made by adding to, deleting,
33 | or substituting -- in part or in whole -- any of the components of the
34 | Original Version, by changing formats or by porting the Font Software to a
35 | new environment.
36 |
37 | "Author" refers to any designer, engineer, programmer, technical
38 | writer or other person who contributed to the Font Software.
39 |
40 | PERMISSION & CONDITIONS
41 | Permission is hereby granted, free of charge, to any person obtaining
42 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
43 | redistribute, and sell modified and unmodified copies of the Font
44 | Software, subject to the following conditions:
45 |
46 | 1) Neither the Font Software nor any of its individual components,
47 | in Original or Modified Versions, may be sold by itself.
48 |
49 | 2) Original or Modified Versions of the Font Software may be bundled,
50 | redistributed and/or sold with any software, provided that each copy
51 | contains the above copyright notice and this license. These can be
52 | included either as stand-alone text files, human-readable headers or
53 | in the appropriate machine-readable metadata fields within text or
54 | binary files as long as those fields can be easily viewed by the user.
55 |
56 | 3) No Modified Version of the Font Software may use the Reserved Font
57 | Name(s) unless explicit written permission is granted by the corresponding
58 | Copyright Holder. This restriction only applies to the primary font name as
59 | presented to the users.
60 |
61 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
62 | Software shall not be used to promote, endorse or advertise any
63 | Modified Version, except to acknowledge the contribution(s) of the
64 | Copyright Holder(s) and the Author(s) or with their explicit written
65 | permission.
66 |
67 | 5) The Font Software, modified or unmodified, in part or in whole,
68 | must be distributed entirely under this license, and must not be
69 | distributed under any other license. The requirement for fonts to
70 | remain under this license does not apply to any document created
71 | using the Font Software.
72 |
73 | TERMINATION
74 | This license becomes null and void if any of the above conditions are
75 | not met.
76 |
77 | DISCLAIMER
78 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
79 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
80 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
81 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
82 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
83 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
84 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
85 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
86 | OTHER DEALINGS IN THE FONT SOFTWARE.
87 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/ICON-LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Waybury
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/README.md:
--------------------------------------------------------------------------------
1 | [Open Iconic v1.1.1](https://github.com/iconic/open-iconic)
2 | ===========
3 |
4 | ### Open Iconic is the open source sibling of [Iconic](https://github.com/iconic/open-iconic). It is a hyper-legible collection of 223 icons with a tiny footprint—ready to use with Bootstrap and Foundation. [View the collection](https://github.com/iconic/open-iconic)
5 |
6 |
7 |
8 | ## What's in Open Iconic?
9 |
10 | * 223 icons designed to be legible down to 8 pixels
11 | * Super-light SVG files - 61.8 for the entire set
12 | * SVG sprite—the modern replacement for icon fonts
13 | * Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats
14 | * Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats
15 | * PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.
16 |
17 |
18 | ## Getting Started
19 |
20 | #### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](https://github.com/iconic/open-iconic) and [Reference](https://github.com/iconic/open-iconic) sections.
21 |
22 | ### General Usage
23 |
24 | #### Using Open Iconic's SVGs
25 |
26 | We like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).
27 |
28 | ```
29 |
30 | ```
31 |
32 | #### Using Open Iconic's SVG Sprite
33 |
34 | Open Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.
35 |
36 | Adding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `` *tag and a unique class name for each different icon in the* `` *tag.*
37 |
38 | ```
39 |
40 |
41 |
42 | ```
43 |
44 | Sizing icons only needs basic CSS. All the icons are in a square format, so just set the `` tag with equal width and height dimensions.
45 |
46 | ```
47 | .icon {
48 | width: 16px;
49 | height: 16px;
50 | }
51 | ```
52 |
53 | Coloring icons is even easier. All you need to do is set the `fill` rule on the `` tag.
54 |
55 | ```
56 | .icon-account-login {
57 | fill: #f00;
58 | }
59 | ```
60 |
61 | To learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/).
62 |
63 | #### Using Open Iconic's Icon Font...
64 |
65 |
66 | ##### …with Bootstrap
67 |
68 | You can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}`
69 |
70 |
71 | ```
72 |
73 | ```
74 |
75 |
76 | ```
77 |
78 | ```
79 |
80 | ##### …with Foundation
81 |
82 | You can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}`
83 |
84 | ```
85 |
86 | ```
87 |
88 |
89 | ```
90 |
91 | ```
92 |
93 | ##### …on its own
94 |
95 | You can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}`
96 |
97 | ```
98 |
99 | ```
100 |
101 | ```
102 |
103 | ```
104 |
105 |
106 | ## License
107 |
108 | ### Icons
109 |
110 | All code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT).
111 |
112 | ### Fonts
113 |
114 | All fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web).
115 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css:
--------------------------------------------------------------------------------
1 | @font-face{font-family:Icons;src:url(../fonts/open-iconic.eot);src:url(../fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'),url(../fonts/open-iconic.woff) format('woff'),url(../fonts/open-iconic.ttf) format('truetype'),url(../fonts/open-iconic.otf) format('opentype'),url(../fonts/open-iconic.svg#iconic-sm) format('svg');font-weight:400;font-style:normal}.oi{position:relative;top:1px;display:inline-block;speak:none;font-family:Icons;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.oi:empty:before{width:1em;text-align:center;box-sizing:content-box}.oi.oi-align-center:before{text-align:center}.oi.oi-align-left:before{text-align:left}.oi.oi-align-right:before{text-align:right}.oi.oi-flip-horizontal:before{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.oi.oi-flip-vertical:before{-webkit-transform:scale(1,-1);-ms-transform:scale(-1,1);transform:scale(1,-1)}.oi.oi-flip-horizontal-vertical:before{-webkit-transform:scale(-1,-1);-ms-transform:scale(-1,1);transform:scale(-1,-1)}.oi-account-login:before{content:'\e000'}.oi-account-logout:before{content:'\e001'}.oi-action-redo:before{content:'\e002'}.oi-action-undo:before{content:'\e003'}.oi-align-center:before{content:'\e004'}.oi-align-left:before{content:'\e005'}.oi-align-right:before{content:'\e006'}.oi-aperture:before{content:'\e007'}.oi-arrow-bottom:before{content:'\e008'}.oi-arrow-circle-bottom:before{content:'\e009'}.oi-arrow-circle-left:before{content:'\e00a'}.oi-arrow-circle-right:before{content:'\e00b'}.oi-arrow-circle-top:before{content:'\e00c'}.oi-arrow-left:before{content:'\e00d'}.oi-arrow-right:before{content:'\e00e'}.oi-arrow-thick-bottom:before{content:'\e00f'}.oi-arrow-thick-left:before{content:'\e010'}.oi-arrow-thick-right:before{content:'\e011'}.oi-arrow-thick-top:before{content:'\e012'}.oi-arrow-top:before{content:'\e013'}.oi-audio-spectrum:before{content:'\e014'}.oi-audio:before{content:'\e015'}.oi-badge:before{content:'\e016'}.oi-ban:before{content:'\e017'}.oi-bar-chart:before{content:'\e018'}.oi-basket:before{content:'\e019'}.oi-battery-empty:before{content:'\e01a'}.oi-battery-full:before{content:'\e01b'}.oi-beaker:before{content:'\e01c'}.oi-bell:before{content:'\e01d'}.oi-bluetooth:before{content:'\e01e'}.oi-bold:before{content:'\e01f'}.oi-bolt:before{content:'\e020'}.oi-book:before{content:'\e021'}.oi-bookmark:before{content:'\e022'}.oi-box:before{content:'\e023'}.oi-briefcase:before{content:'\e024'}.oi-british-pound:before{content:'\e025'}.oi-browser:before{content:'\e026'}.oi-brush:before{content:'\e027'}.oi-bug:before{content:'\e028'}.oi-bullhorn:before{content:'\e029'}.oi-calculator:before{content:'\e02a'}.oi-calendar:before{content:'\e02b'}.oi-camera-slr:before{content:'\e02c'}.oi-caret-bottom:before{content:'\e02d'}.oi-caret-left:before{content:'\e02e'}.oi-caret-right:before{content:'\e02f'}.oi-caret-top:before{content:'\e030'}.oi-cart:before{content:'\e031'}.oi-chat:before{content:'\e032'}.oi-check:before{content:'\e033'}.oi-chevron-bottom:before{content:'\e034'}.oi-chevron-left:before{content:'\e035'}.oi-chevron-right:before{content:'\e036'}.oi-chevron-top:before{content:'\e037'}.oi-circle-check:before{content:'\e038'}.oi-circle-x:before{content:'\e039'}.oi-clipboard:before{content:'\e03a'}.oi-clock:before{content:'\e03b'}.oi-cloud-download:before{content:'\e03c'}.oi-cloud-upload:before{content:'\e03d'}.oi-cloud:before{content:'\e03e'}.oi-cloudy:before{content:'\e03f'}.oi-code:before{content:'\e040'}.oi-cog:before{content:'\e041'}.oi-collapse-down:before{content:'\e042'}.oi-collapse-left:before{content:'\e043'}.oi-collapse-right:before{content:'\e044'}.oi-collapse-up:before{content:'\e045'}.oi-command:before{content:'\e046'}.oi-comment-square:before{content:'\e047'}.oi-compass:before{content:'\e048'}.oi-contrast:before{content:'\e049'}.oi-copywriting:before{content:'\e04a'}.oi-credit-card:before{content:'\e04b'}.oi-crop:before{content:'\e04c'}.oi-dashboard:before{content:'\e04d'}.oi-data-transfer-download:before{content:'\e04e'}.oi-data-transfer-upload:before{content:'\e04f'}.oi-delete:before{content:'\e050'}.oi-dial:before{content:'\e051'}.oi-document:before{content:'\e052'}.oi-dollar:before{content:'\e053'}.oi-double-quote-sans-left:before{content:'\e054'}.oi-double-quote-sans-right:before{content:'\e055'}.oi-double-quote-serif-left:before{content:'\e056'}.oi-double-quote-serif-right:before{content:'\e057'}.oi-droplet:before{content:'\e058'}.oi-eject:before{content:'\e059'}.oi-elevator:before{content:'\e05a'}.oi-ellipses:before{content:'\e05b'}.oi-envelope-closed:before{content:'\e05c'}.oi-envelope-open:before{content:'\e05d'}.oi-euro:before{content:'\e05e'}.oi-excerpt:before{content:'\e05f'}.oi-expand-down:before{content:'\e060'}.oi-expand-left:before{content:'\e061'}.oi-expand-right:before{content:'\e062'}.oi-expand-up:before{content:'\e063'}.oi-external-link:before{content:'\e064'}.oi-eye:before{content:'\e065'}.oi-eyedropper:before{content:'\e066'}.oi-file:before{content:'\e067'}.oi-fire:before{content:'\e068'}.oi-flag:before{content:'\e069'}.oi-flash:before{content:'\e06a'}.oi-folder:before{content:'\e06b'}.oi-fork:before{content:'\e06c'}.oi-fullscreen-enter:before{content:'\e06d'}.oi-fullscreen-exit:before{content:'\e06e'}.oi-globe:before{content:'\e06f'}.oi-graph:before{content:'\e070'}.oi-grid-four-up:before{content:'\e071'}.oi-grid-three-up:before{content:'\e072'}.oi-grid-two-up:before{content:'\e073'}.oi-hard-drive:before{content:'\e074'}.oi-header:before{content:'\e075'}.oi-headphones:before{content:'\e076'}.oi-heart:before{content:'\e077'}.oi-home:before{content:'\e078'}.oi-image:before{content:'\e079'}.oi-inbox:before{content:'\e07a'}.oi-infinity:before{content:'\e07b'}.oi-info:before{content:'\e07c'}.oi-italic:before{content:'\e07d'}.oi-justify-center:before{content:'\e07e'}.oi-justify-left:before{content:'\e07f'}.oi-justify-right:before{content:'\e080'}.oi-key:before{content:'\e081'}.oi-laptop:before{content:'\e082'}.oi-layers:before{content:'\e083'}.oi-lightbulb:before{content:'\e084'}.oi-link-broken:before{content:'\e085'}.oi-link-intact:before{content:'\e086'}.oi-list-rich:before{content:'\e087'}.oi-list:before{content:'\e088'}.oi-location:before{content:'\e089'}.oi-lock-locked:before{content:'\e08a'}.oi-lock-unlocked:before{content:'\e08b'}.oi-loop-circular:before{content:'\e08c'}.oi-loop-square:before{content:'\e08d'}.oi-loop:before{content:'\e08e'}.oi-magnifying-glass:before{content:'\e08f'}.oi-map-marker:before{content:'\e090'}.oi-map:before{content:'\e091'}.oi-media-pause:before{content:'\e092'}.oi-media-play:before{content:'\e093'}.oi-media-record:before{content:'\e094'}.oi-media-skip-backward:before{content:'\e095'}.oi-media-skip-forward:before{content:'\e096'}.oi-media-step-backward:before{content:'\e097'}.oi-media-step-forward:before{content:'\e098'}.oi-media-stop:before{content:'\e099'}.oi-medical-cross:before{content:'\e09a'}.oi-menu:before{content:'\e09b'}.oi-microphone:before{content:'\e09c'}.oi-minus:before{content:'\e09d'}.oi-monitor:before{content:'\e09e'}.oi-moon:before{content:'\e09f'}.oi-move:before{content:'\e0a0'}.oi-musical-note:before{content:'\e0a1'}.oi-paperclip:before{content:'\e0a2'}.oi-pencil:before{content:'\e0a3'}.oi-people:before{content:'\e0a4'}.oi-person:before{content:'\e0a5'}.oi-phone:before{content:'\e0a6'}.oi-pie-chart:before{content:'\e0a7'}.oi-pin:before{content:'\e0a8'}.oi-play-circle:before{content:'\e0a9'}.oi-plus:before{content:'\e0aa'}.oi-power-standby:before{content:'\e0ab'}.oi-print:before{content:'\e0ac'}.oi-project:before{content:'\e0ad'}.oi-pulse:before{content:'\e0ae'}.oi-puzzle-piece:before{content:'\e0af'}.oi-question-mark:before{content:'\e0b0'}.oi-rain:before{content:'\e0b1'}.oi-random:before{content:'\e0b2'}.oi-reload:before{content:'\e0b3'}.oi-resize-both:before{content:'\e0b4'}.oi-resize-height:before{content:'\e0b5'}.oi-resize-width:before{content:'\e0b6'}.oi-rss-alt:before{content:'\e0b7'}.oi-rss:before{content:'\e0b8'}.oi-script:before{content:'\e0b9'}.oi-share-boxed:before{content:'\e0ba'}.oi-share:before{content:'\e0bb'}.oi-shield:before{content:'\e0bc'}.oi-signal:before{content:'\e0bd'}.oi-signpost:before{content:'\e0be'}.oi-sort-ascending:before{content:'\e0bf'}.oi-sort-descending:before{content:'\e0c0'}.oi-spreadsheet:before{content:'\e0c1'}.oi-star:before{content:'\e0c2'}.oi-sun:before{content:'\e0c3'}.oi-tablet:before{content:'\e0c4'}.oi-tag:before{content:'\e0c5'}.oi-tags:before{content:'\e0c6'}.oi-target:before{content:'\e0c7'}.oi-task:before{content:'\e0c8'}.oi-terminal:before{content:'\e0c9'}.oi-text:before{content:'\e0ca'}.oi-thumb-down:before{content:'\e0cb'}.oi-thumb-up:before{content:'\e0cc'}.oi-timer:before{content:'\e0cd'}.oi-transfer:before{content:'\e0ce'}.oi-trash:before{content:'\e0cf'}.oi-underline:before{content:'\e0d0'}.oi-vertical-align-bottom:before{content:'\e0d1'}.oi-vertical-align-center:before{content:'\e0d2'}.oi-vertical-align-top:before{content:'\e0d3'}.oi-video:before{content:'\e0d4'}.oi-volume-high:before{content:'\e0d5'}.oi-volume-low:before{content:'\e0d6'}.oi-volume-off:before{content:'\e0d7'}.oi-warning:before{content:'\e0d8'}.oi-wifi:before{content:'\e0d9'}.oi-wrench:before{content:'\e0da'}.oi-x:before{content:'\e0db'}.oi-yen:before{content:'\e0dc'}.oi-zoom-in:before{content:'\e0dd'}.oi-zoom-out:before{content:'\e0de'}
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.eot
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.otf
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 | Created by FontForge 20120731 at Tue Jul 1 20:39:22 2014
9 | By P.J. Onori
10 | Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net)
11 |
12 |
13 |
14 |
27 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
45 |
47 |
49 |
51 |
53 |
55 |
57 |
59 |
61 |
63 |
65 |
67 |
69 |
71 |
74 |
76 |
79 |
81 |
84 |
86 |
88 |
91 |
93 |
95 |
98 |
100 |
102 |
104 |
106 |
109 |
112 |
115 |
117 |
121 |
123 |
125 |
127 |
130 |
132 |
134 |
136 |
138 |
141 |
143 |
145 |
147 |
149 |
151 |
153 |
155 |
157 |
159 |
162 |
165 |
167 |
169 |
172 |
174 |
177 |
179 |
181 |
183 |
185 |
189 |
191 |
194 |
196 |
198 |
200 |
202 |
205 |
207 |
209 |
211 |
213 |
215 |
218 |
220 |
222 |
224 |
226 |
228 |
230 |
232 |
234 |
236 |
238 |
241 |
243 |
245 |
247 |
249 |
251 |
253 |
256 |
259 |
261 |
263 |
265 |
267 |
269 |
272 |
274 |
276 |
280 |
282 |
285 |
287 |
289 |
292 |
295 |
298 |
300 |
302 |
304 |
306 |
309 |
312 |
314 |
316 |
318 |
320 |
322 |
324 |
326 |
330 |
334 |
338 |
340 |
343 |
345 |
347 |
349 |
351 |
353 |
355 |
358 |
360 |
363 |
365 |
367 |
369 |
371 |
373 |
375 |
377 |
379 |
381 |
383 |
386 |
388 |
390 |
392 |
394 |
396 |
399 |
401 |
404 |
406 |
408 |
410 |
412 |
414 |
416 |
419 |
421 |
423 |
425 |
428 |
431 |
435 |
438 |
440 |
442 |
444 |
446 |
448 |
451 |
453 |
455 |
457 |
460 |
462 |
464 |
466 |
468 |
471 |
473 |
477 |
479 |
481 |
483 |
486 |
488 |
490 |
492 |
494 |
496 |
499 |
501 |
504 |
506 |
509 |
512 |
515 |
517 |
520 |
522 |
524 |
526 |
529 |
532 |
534 |
536 |
539 |
542 |
543 |
544 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/css/open-iconic/font/fonts/open-iconic.woff
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/favicon.png
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stavroskasidis/BlazorWithIdentity/f26d28fce6c6a52126634ba8131054c3ee77ffd0/template/BlazorWithIdentity.Client/wwwroot/icon-192.png
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Client/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | BlazorWithIdentity
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | An unhandled error has occurred.
26 |
Reload
27 |
🗙
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/BlazorWithIdentity.Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net7.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Controllers/AuthorizeController.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Server.Models;
2 | using BlazorWithIdentity.Shared;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Identity;
5 | using Microsoft.AspNetCore.Mvc;
6 |
7 | namespace BlazorWithIdentity.Server.Controllers
8 | {
9 | [Route("api/[controller]/[action]")]
10 | [ApiController]
11 | public class AuthorizeController : ControllerBase
12 | {
13 | private readonly UserManager _userManager;
14 | private readonly SignInManager _signInManager;
15 |
16 | public AuthorizeController(UserManager userManager, SignInManager signInManager)
17 | {
18 | _userManager = userManager;
19 | _signInManager = signInManager;
20 | }
21 |
22 | [HttpPost]
23 | public async Task Login(LoginParameters parameters)
24 | {
25 | var user = await _userManager.FindByNameAsync(parameters.UserName);
26 | if (user == null) return BadRequest("User does not exist");
27 | var singInResult = await _signInManager.CheckPasswordSignInAsync(user, parameters.Password, false);
28 | if (!singInResult.Succeeded) return BadRequest("Invalid password");
29 |
30 | await _signInManager.SignInAsync(user, parameters.RememberMe);
31 |
32 | return Ok();
33 | }
34 |
35 |
36 | [HttpPost]
37 | public async Task Register(RegisterParameters parameters)
38 | {
39 | var user = new ApplicationUser();
40 | user.UserName = parameters.UserName;
41 | var result = await _userManager.CreateAsync(user, parameters.Password);
42 | if (!result.Succeeded) return BadRequest(result.Errors.FirstOrDefault()?.Description);
43 |
44 | return await Login(new LoginParameters
45 | {
46 | UserName = parameters.UserName,
47 | Password = parameters.Password
48 | });
49 | }
50 |
51 | [Authorize]
52 | [HttpPost]
53 | public async Task Logout()
54 | {
55 | await _signInManager.SignOutAsync();
56 | return Ok();
57 | }
58 |
59 | [HttpGet]
60 | public UserInfo UserInfo()
61 | {
62 | //var user = await _userManager.GetUserAsync(HttpContext.User);
63 | return BuildUserInfo();
64 | }
65 |
66 |
67 | private UserInfo BuildUserInfo()
68 | {
69 | return new UserInfo
70 | {
71 | IsAuthenticated = User.Identity.IsAuthenticated,
72 | UserName = User.Identity.Name,
73 | ExposedClaims = User.Claims
74 | //Optionally: filter the claims you want to expose to the client
75 | //.Where(c => c.Type == "test-claim")
76 | .ToDictionary(c => c.Type, c => c.Value)
77 | };
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Controllers/SampleDataController.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Shared;
2 | using Microsoft.AspNetCore.Authorization;
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | namespace BlazorWithIdentity.Server.Controllers
6 | {
7 | [Route("api/[controller]")]
8 | [Authorize]
9 | public class SampleDataController : Controller
10 | {
11 | private static string[] Summaries = new[]
12 | {
13 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
14 | };
15 |
16 | [HttpGet("[action]")]
17 | public IEnumerable WeatherForecasts()
18 | {
19 | var rng = new Random();
20 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast
21 | {
22 | Date = DateTime.Now.AddDays(index),
23 | TemperatureC = rng.Next(-20, 55),
24 | Summary = Summaries[rng.Next(Summaries.Length)]
25 | });
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Data/ApplicationDbContext.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Server.Models;
2 | using Microsoft.AspNetCore.Identity;
3 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
4 | using Microsoft.EntityFrameworkCore;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Threading.Tasks;
9 |
10 | namespace BlazorWithIdentity.Server.Data
11 | {
12 | public class ApplicationDbContext : IdentityDbContext, Guid>
13 | {
14 | public ApplicationDbContext(DbContextOptions options)
15 | : base(options)
16 | {
17 | }
18 |
19 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
20 | {
21 | base.OnConfiguring(optionsBuilder);
22 | }
23 |
24 | protected override void OnModelCreating(ModelBuilder builder)
25 | {
26 | base.OnModelCreating(builder);
27 | // Customize the ASP.NET Identity model and override the defaults if needed.
28 | // For example, you can rename the ASP.NET Identity table names and more.
29 | // Add your customizations after calling base.OnModelCreating(builder);
30 |
31 | }
32 |
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Migrations/20190502083628_Init.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using BlazorWithIdentity.Server.Data;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Migrations;
7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
8 |
9 | namespace BlazorWithIdentity.Server.Migrations
10 | {
11 | [DbContext(typeof(ApplicationDbContext))]
12 | [Migration("20190502083628_Init")]
13 | partial class Init
14 | {
15 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
16 | {
17 | #pragma warning disable 612, 618
18 | modelBuilder
19 | .HasAnnotation("ProductVersion", "3.0.0-preview3.19153.1");
20 |
21 | modelBuilder.Entity("BlazorWithIdentity.Server.Models.ApplicationUser", b =>
22 | {
23 | b.Property("Id")
24 | .ValueGeneratedOnAdd();
25 |
26 | b.Property("AccessFailedCount");
27 |
28 | b.Property("ConcurrencyStamp")
29 | .IsConcurrencyToken();
30 |
31 | b.Property("Email")
32 | .HasMaxLength(256);
33 |
34 | b.Property("EmailConfirmed");
35 |
36 | b.Property("LockoutEnabled");
37 |
38 | b.Property("LockoutEnd");
39 |
40 | b.Property("NormalizedEmail")
41 | .HasMaxLength(256);
42 |
43 | b.Property("NormalizedUserName")
44 | .HasMaxLength(256);
45 |
46 | b.Property("PasswordHash");
47 |
48 | b.Property("PhoneNumber");
49 |
50 | b.Property("PhoneNumberConfirmed");
51 |
52 | b.Property("SecurityStamp");
53 |
54 | b.Property("TwoFactorEnabled");
55 |
56 | b.Property("UserName")
57 | .HasMaxLength(256);
58 |
59 | b.HasKey("Id");
60 |
61 | b.HasIndex("NormalizedEmail")
62 | .HasName("EmailIndex");
63 |
64 | b.HasIndex("NormalizedUserName")
65 | .IsUnique()
66 | .HasName("UserNameIndex");
67 |
68 | b.ToTable("AspNetUsers");
69 | });
70 |
71 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
72 | {
73 | b.Property("Id")
74 | .ValueGeneratedOnAdd();
75 |
76 | b.Property("ConcurrencyStamp")
77 | .IsConcurrencyToken();
78 |
79 | b.Property("Name")
80 | .HasMaxLength(256);
81 |
82 | b.Property("NormalizedName")
83 | .HasMaxLength(256);
84 |
85 | b.HasKey("Id");
86 |
87 | b.HasIndex("NormalizedName")
88 | .IsUnique()
89 | .HasName("RoleNameIndex");
90 |
91 | b.ToTable("AspNetRoles");
92 | });
93 |
94 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
95 | {
96 | b.Property("Id")
97 | .ValueGeneratedOnAdd();
98 |
99 | b.Property("ClaimType");
100 |
101 | b.Property("ClaimValue");
102 |
103 | b.Property("RoleId");
104 |
105 | b.HasKey("Id");
106 |
107 | b.HasIndex("RoleId");
108 |
109 | b.ToTable("AspNetRoleClaims");
110 | });
111 |
112 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
113 | {
114 | b.Property("Id")
115 | .ValueGeneratedOnAdd();
116 |
117 | b.Property("ClaimType");
118 |
119 | b.Property("ClaimValue");
120 |
121 | b.Property("UserId");
122 |
123 | b.HasKey("Id");
124 |
125 | b.HasIndex("UserId");
126 |
127 | b.ToTable("AspNetUserClaims");
128 | });
129 |
130 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
131 | {
132 | b.Property("LoginProvider");
133 |
134 | b.Property("ProviderKey");
135 |
136 | b.Property("ProviderDisplayName");
137 |
138 | b.Property("UserId");
139 |
140 | b.HasKey("LoginProvider", "ProviderKey");
141 |
142 | b.HasIndex("UserId");
143 |
144 | b.ToTable("AspNetUserLogins");
145 | });
146 |
147 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
148 | {
149 | b.Property("UserId");
150 |
151 | b.Property("RoleId");
152 |
153 | b.HasKey("UserId", "RoleId");
154 |
155 | b.HasIndex("RoleId");
156 |
157 | b.ToTable("AspNetUserRoles");
158 | });
159 |
160 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
161 | {
162 | b.Property("UserId");
163 |
164 | b.Property("LoginProvider");
165 |
166 | b.Property("Name");
167 |
168 | b.Property("Value");
169 |
170 | b.HasKey("UserId", "LoginProvider", "Name");
171 |
172 | b.ToTable("AspNetUserTokens");
173 | });
174 |
175 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
176 | {
177 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
178 | .WithMany()
179 | .HasForeignKey("RoleId")
180 | .OnDelete(DeleteBehavior.Cascade);
181 | });
182 |
183 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
184 | {
185 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
186 | .WithMany()
187 | .HasForeignKey("UserId")
188 | .OnDelete(DeleteBehavior.Cascade);
189 | });
190 |
191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
192 | {
193 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
194 | .WithMany()
195 | .HasForeignKey("UserId")
196 | .OnDelete(DeleteBehavior.Cascade);
197 | });
198 |
199 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
200 | {
201 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
202 | .WithMany()
203 | .HasForeignKey("RoleId")
204 | .OnDelete(DeleteBehavior.Cascade);
205 |
206 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
207 | .WithMany()
208 | .HasForeignKey("UserId")
209 | .OnDelete(DeleteBehavior.Cascade);
210 | });
211 |
212 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
213 | {
214 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
215 | .WithMany()
216 | .HasForeignKey("UserId")
217 | .OnDelete(DeleteBehavior.Cascade);
218 | });
219 | #pragma warning restore 612, 618
220 | }
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Migrations/20190502083628_Init.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Migrations;
3 |
4 | namespace BlazorWithIdentity.Server.Migrations
5 | {
6 | public partial class Init : Migration
7 | {
8 | protected override void Up(MigrationBuilder migrationBuilder)
9 | {
10 | migrationBuilder.CreateTable(
11 | name: "AspNetRoles",
12 | columns: table => new
13 | {
14 | Id = table.Column(nullable: false),
15 | Name = table.Column(maxLength: 256, nullable: true),
16 | NormalizedName = table.Column(maxLength: 256, nullable: true),
17 | ConcurrencyStamp = table.Column(nullable: true)
18 | },
19 | constraints: table =>
20 | {
21 | table.PrimaryKey("PK_AspNetRoles", x => x.Id);
22 | });
23 |
24 | migrationBuilder.CreateTable(
25 | name: "AspNetUsers",
26 | columns: table => new
27 | {
28 | Id = table.Column(nullable: false),
29 | UserName = table.Column(maxLength: 256, nullable: true),
30 | NormalizedUserName = table.Column(maxLength: 256, nullable: true),
31 | Email = table.Column(maxLength: 256, nullable: true),
32 | NormalizedEmail = table.Column(maxLength: 256, nullable: true),
33 | EmailConfirmed = table.Column(nullable: false),
34 | PasswordHash = table.Column(nullable: true),
35 | SecurityStamp = table.Column(nullable: true),
36 | ConcurrencyStamp = table.Column(nullable: true),
37 | PhoneNumber = table.Column(nullable: true),
38 | PhoneNumberConfirmed = table.Column(nullable: false),
39 | TwoFactorEnabled = table.Column(nullable: false),
40 | LockoutEnd = table.Column(nullable: true),
41 | LockoutEnabled = table.Column(nullable: false),
42 | AccessFailedCount = table.Column(nullable: false)
43 | },
44 | constraints: table =>
45 | {
46 | table.PrimaryKey("PK_AspNetUsers", x => x.Id);
47 | });
48 |
49 | migrationBuilder.CreateTable(
50 | name: "AspNetRoleClaims",
51 | columns: table => new
52 | {
53 | Id = table.Column(nullable: false)
54 | .Annotation("Sqlite:Autoincrement", true),
55 | RoleId = table.Column(nullable: false),
56 | ClaimType = table.Column(nullable: true),
57 | ClaimValue = table.Column(nullable: true)
58 | },
59 | constraints: table =>
60 | {
61 | table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
62 | table.ForeignKey(
63 | name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
64 | column: x => x.RoleId,
65 | principalTable: "AspNetRoles",
66 | principalColumn: "Id",
67 | onDelete: ReferentialAction.Cascade);
68 | });
69 |
70 | migrationBuilder.CreateTable(
71 | name: "AspNetUserClaims",
72 | columns: table => new
73 | {
74 | Id = table.Column(nullable: false)
75 | .Annotation("Sqlite:Autoincrement", true),
76 | UserId = table.Column(nullable: false),
77 | ClaimType = table.Column(nullable: true),
78 | ClaimValue = table.Column(nullable: true)
79 | },
80 | constraints: table =>
81 | {
82 | table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
83 | table.ForeignKey(
84 | name: "FK_AspNetUserClaims_AspNetUsers_UserId",
85 | column: x => x.UserId,
86 | principalTable: "AspNetUsers",
87 | principalColumn: "Id",
88 | onDelete: ReferentialAction.Cascade);
89 | });
90 |
91 | migrationBuilder.CreateTable(
92 | name: "AspNetUserLogins",
93 | columns: table => new
94 | {
95 | LoginProvider = table.Column(nullable: false),
96 | ProviderKey = table.Column(nullable: false),
97 | ProviderDisplayName = table.Column(nullable: true),
98 | UserId = table.Column(nullable: false)
99 | },
100 | constraints: table =>
101 | {
102 | table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
103 | table.ForeignKey(
104 | name: "FK_AspNetUserLogins_AspNetUsers_UserId",
105 | column: x => x.UserId,
106 | principalTable: "AspNetUsers",
107 | principalColumn: "Id",
108 | onDelete: ReferentialAction.Cascade);
109 | });
110 |
111 | migrationBuilder.CreateTable(
112 | name: "AspNetUserRoles",
113 | columns: table => new
114 | {
115 | UserId = table.Column(nullable: false),
116 | RoleId = table.Column(nullable: false)
117 | },
118 | constraints: table =>
119 | {
120 | table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
121 | table.ForeignKey(
122 | name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
123 | column: x => x.RoleId,
124 | principalTable: "AspNetRoles",
125 | principalColumn: "Id",
126 | onDelete: ReferentialAction.Cascade);
127 | table.ForeignKey(
128 | name: "FK_AspNetUserRoles_AspNetUsers_UserId",
129 | column: x => x.UserId,
130 | principalTable: "AspNetUsers",
131 | principalColumn: "Id",
132 | onDelete: ReferentialAction.Cascade);
133 | });
134 |
135 | migrationBuilder.CreateTable(
136 | name: "AspNetUserTokens",
137 | columns: table => new
138 | {
139 | UserId = table.Column(nullable: false),
140 | LoginProvider = table.Column(nullable: false),
141 | Name = table.Column(nullable: false),
142 | Value = table.Column(nullable: true)
143 | },
144 | constraints: table =>
145 | {
146 | table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
147 | table.ForeignKey(
148 | name: "FK_AspNetUserTokens_AspNetUsers_UserId",
149 | column: x => x.UserId,
150 | principalTable: "AspNetUsers",
151 | principalColumn: "Id",
152 | onDelete: ReferentialAction.Cascade);
153 | });
154 |
155 | migrationBuilder.CreateIndex(
156 | name: "IX_AspNetRoleClaims_RoleId",
157 | table: "AspNetRoleClaims",
158 | column: "RoleId");
159 |
160 | migrationBuilder.CreateIndex(
161 | name: "RoleNameIndex",
162 | table: "AspNetRoles",
163 | column: "NormalizedName",
164 | unique: true);
165 |
166 | migrationBuilder.CreateIndex(
167 | name: "IX_AspNetUserClaims_UserId",
168 | table: "AspNetUserClaims",
169 | column: "UserId");
170 |
171 | migrationBuilder.CreateIndex(
172 | name: "IX_AspNetUserLogins_UserId",
173 | table: "AspNetUserLogins",
174 | column: "UserId");
175 |
176 | migrationBuilder.CreateIndex(
177 | name: "IX_AspNetUserRoles_RoleId",
178 | table: "AspNetUserRoles",
179 | column: "RoleId");
180 |
181 | migrationBuilder.CreateIndex(
182 | name: "EmailIndex",
183 | table: "AspNetUsers",
184 | column: "NormalizedEmail");
185 |
186 | migrationBuilder.CreateIndex(
187 | name: "UserNameIndex",
188 | table: "AspNetUsers",
189 | column: "NormalizedUserName",
190 | unique: true);
191 | }
192 |
193 | protected override void Down(MigrationBuilder migrationBuilder)
194 | {
195 | migrationBuilder.DropTable(
196 | name: "AspNetRoleClaims");
197 |
198 | migrationBuilder.DropTable(
199 | name: "AspNetUserClaims");
200 |
201 | migrationBuilder.DropTable(
202 | name: "AspNetUserLogins");
203 |
204 | migrationBuilder.DropTable(
205 | name: "AspNetUserRoles");
206 |
207 | migrationBuilder.DropTable(
208 | name: "AspNetUserTokens");
209 |
210 | migrationBuilder.DropTable(
211 | name: "AspNetRoles");
212 |
213 | migrationBuilder.DropTable(
214 | name: "AspNetUsers");
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Migrations/ApplicationDbContextModelSnapshot.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using BlazorWithIdentity.Server.Data;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
7 |
8 | namespace BlazorWithIdentity.Server.Migrations
9 | {
10 | [DbContext(typeof(ApplicationDbContext))]
11 | partial class ApplicationDbContextModelSnapshot : ModelSnapshot
12 | {
13 | protected override void BuildModel(ModelBuilder modelBuilder)
14 | {
15 | #pragma warning disable 612, 618
16 | modelBuilder
17 | .HasAnnotation("ProductVersion", "3.0.0-preview3.19153.1");
18 |
19 | modelBuilder.Entity("BlazorWithIdentity.Server.Models.ApplicationUser", b =>
20 | {
21 | b.Property("Id")
22 | .ValueGeneratedOnAdd();
23 |
24 | b.Property("AccessFailedCount");
25 |
26 | b.Property("ConcurrencyStamp")
27 | .IsConcurrencyToken();
28 |
29 | b.Property("Email")
30 | .HasMaxLength(256);
31 |
32 | b.Property("EmailConfirmed");
33 |
34 | b.Property("LockoutEnabled");
35 |
36 | b.Property("LockoutEnd");
37 |
38 | b.Property("NormalizedEmail")
39 | .HasMaxLength(256);
40 |
41 | b.Property("NormalizedUserName")
42 | .HasMaxLength(256);
43 |
44 | b.Property("PasswordHash");
45 |
46 | b.Property("PhoneNumber");
47 |
48 | b.Property("PhoneNumberConfirmed");
49 |
50 | b.Property("SecurityStamp");
51 |
52 | b.Property("TwoFactorEnabled");
53 |
54 | b.Property("UserName")
55 | .HasMaxLength(256);
56 |
57 | b.HasKey("Id");
58 |
59 | b.HasIndex("NormalizedEmail")
60 | .HasName("EmailIndex");
61 |
62 | b.HasIndex("NormalizedUserName")
63 | .IsUnique()
64 | .HasName("UserNameIndex");
65 |
66 | b.ToTable("AspNetUsers");
67 | });
68 |
69 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
70 | {
71 | b.Property("Id")
72 | .ValueGeneratedOnAdd();
73 |
74 | b.Property("ConcurrencyStamp")
75 | .IsConcurrencyToken();
76 |
77 | b.Property("Name")
78 | .HasMaxLength(256);
79 |
80 | b.Property("NormalizedName")
81 | .HasMaxLength(256);
82 |
83 | b.HasKey("Id");
84 |
85 | b.HasIndex("NormalizedName")
86 | .IsUnique()
87 | .HasName("RoleNameIndex");
88 |
89 | b.ToTable("AspNetRoles");
90 | });
91 |
92 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
93 | {
94 | b.Property("Id")
95 | .ValueGeneratedOnAdd();
96 |
97 | b.Property("ClaimType");
98 |
99 | b.Property("ClaimValue");
100 |
101 | b.Property("RoleId");
102 |
103 | b.HasKey("Id");
104 |
105 | b.HasIndex("RoleId");
106 |
107 | b.ToTable("AspNetRoleClaims");
108 | });
109 |
110 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
111 | {
112 | b.Property("Id")
113 | .ValueGeneratedOnAdd();
114 |
115 | b.Property("ClaimType");
116 |
117 | b.Property("ClaimValue");
118 |
119 | b.Property("UserId");
120 |
121 | b.HasKey("Id");
122 |
123 | b.HasIndex("UserId");
124 |
125 | b.ToTable("AspNetUserClaims");
126 | });
127 |
128 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
129 | {
130 | b.Property("LoginProvider");
131 |
132 | b.Property("ProviderKey");
133 |
134 | b.Property("ProviderDisplayName");
135 |
136 | b.Property("UserId");
137 |
138 | b.HasKey("LoginProvider", "ProviderKey");
139 |
140 | b.HasIndex("UserId");
141 |
142 | b.ToTable("AspNetUserLogins");
143 | });
144 |
145 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
146 | {
147 | b.Property("UserId");
148 |
149 | b.Property("RoleId");
150 |
151 | b.HasKey("UserId", "RoleId");
152 |
153 | b.HasIndex("RoleId");
154 |
155 | b.ToTable("AspNetUserRoles");
156 | });
157 |
158 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
159 | {
160 | b.Property("UserId");
161 |
162 | b.Property("LoginProvider");
163 |
164 | b.Property("Name");
165 |
166 | b.Property("Value");
167 |
168 | b.HasKey("UserId", "LoginProvider", "Name");
169 |
170 | b.ToTable("AspNetUserTokens");
171 | });
172 |
173 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
174 | {
175 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
176 | .WithMany()
177 | .HasForeignKey("RoleId")
178 | .OnDelete(DeleteBehavior.Cascade);
179 | });
180 |
181 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
182 | {
183 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
184 | .WithMany()
185 | .HasForeignKey("UserId")
186 | .OnDelete(DeleteBehavior.Cascade);
187 | });
188 |
189 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
190 | {
191 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
192 | .WithMany()
193 | .HasForeignKey("UserId")
194 | .OnDelete(DeleteBehavior.Cascade);
195 | });
196 |
197 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
198 | {
199 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
200 | .WithMany()
201 | .HasForeignKey("RoleId")
202 | .OnDelete(DeleteBehavior.Cascade);
203 |
204 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
205 | .WithMany()
206 | .HasForeignKey("UserId")
207 | .OnDelete(DeleteBehavior.Cascade);
208 | });
209 |
210 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
211 | {
212 | b.HasOne("BlazorWithIdentity.Server.Models.ApplicationUser")
213 | .WithMany()
214 | .HasForeignKey("UserId")
215 | .OnDelete(DeleteBehavior.Cascade);
216 | });
217 | #pragma warning restore 612, 618
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Models/ApplicationUser.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Identity;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace BlazorWithIdentity.Server.Models
8 | {
9 | public class ApplicationUser : IdentityUser
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Program.cs:
--------------------------------------------------------------------------------
1 | using BlazorWithIdentity.Server.Data;
2 | using BlazorWithIdentity.Server.Models;
3 | using Microsoft.AspNetCore.Identity;
4 | using Microsoft.EntityFrameworkCore;
5 |
6 | var builder = WebApplication.CreateBuilder(args);
7 |
8 | // Add services to the container.
9 | builder.Services.AddDbContext(options =>
10 | options.UseSqlite("Filename=data.db"));
11 |
12 | builder.Services.AddIdentity>()
13 | .AddEntityFrameworkStores()
14 | .AddDefaultTokenProviders();
15 |
16 | builder.Services.Configure(options =>
17 | {
18 | // Password settings
19 | options.Password.RequireDigit = true;
20 | options.Password.RequiredLength = 6;
21 | options.Password.RequireNonAlphanumeric = true;
22 | options.Password.RequireUppercase = true;
23 | options.Password.RequireLowercase = false;
24 |
25 | // Lockout settings
26 | options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
27 | options.Lockout.MaxFailedAccessAttempts = 10;
28 | options.Lockout.AllowedForNewUsers = true;
29 |
30 | // User settings
31 | options.User.RequireUniqueEmail = false;
32 | });
33 |
34 | builder.Services.ConfigureApplicationCookie(options =>
35 | {
36 | options.Cookie.HttpOnly = true;
37 | options.Events.OnRedirectToLogin = context =>
38 | {
39 | context.Response.StatusCode = 401;
40 | return Task.CompletedTask;
41 | };
42 | });
43 |
44 |
45 | builder.Services.AddControllersWithViews();
46 | builder.Services.AddRazorPages();
47 |
48 | var app = builder.Build();
49 |
50 | // Configure the HTTP request pipeline.
51 | if (app.Environment.IsDevelopment())
52 | {
53 | using (var serviceScope = app.Services.GetRequiredService().CreateScope())
54 | {
55 | //Note: Microsoft recommends to NOT migrate your database at Startup.
56 | //You should consider your migration strategy according to the guidelines.
57 | serviceScope.ServiceProvider.GetRequiredService().Database.Migrate();
58 | }
59 |
60 | app.UseWebAssemblyDebugging();
61 | }
62 | else
63 | {
64 | app.UseExceptionHandler("/Error");
65 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
66 | app.UseHsts();
67 | }
68 |
69 | app.UseHttpsRedirection();
70 |
71 | app.UseBlazorFrameworkFiles();
72 | app.UseStaticFiles();
73 |
74 | app.UseRouting();
75 | app.UseAuthentication();
76 | app.UseAuthorization();
77 |
78 | app.MapRazorPages();
79 | app.MapControllers();
80 | app.MapFallbackToFile("index.html");
81 |
82 | app.Run();
83 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:53415",
7 | "sslPort": 44370
8 | }
9 | },
10 | "profiles": {
11 | "BlazorWithIdentity.Server": {
12 | "commandName": "Project",
13 | "dotnetRunMessages": true,
14 | "launchBrowser": true,
15 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
16 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
17 | "environmentVariables": {
18 | "ASPNETCORE_ENVIRONMENT": "Development"
19 | }
20 | },
21 | "IIS Express": {
22 | "commandName": "IISExpress",
23 | "launchBrowser": true,
24 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
25 | "environmentVariables": {
26 | "ASPNETCORE_ENVIRONMENT": "Development"
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Server/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Shared/BlazorWithIdentity.Shared.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net7.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Shared/LoginParameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Text;
5 |
6 | namespace BlazorWithIdentity.Shared
7 | {
8 | public class LoginParameters
9 | {
10 | [Required]
11 | public string UserName { get; set; }
12 |
13 | [Required]
14 | public string Password { get; set; }
15 |
16 | public bool RememberMe { get; set; }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Shared/RegisterParameters.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Text;
5 |
6 | namespace BlazorWithIdentity.Shared
7 | {
8 | public class RegisterParameters
9 | {
10 | [Required]
11 | public string UserName { get; set; }
12 |
13 | [Required]
14 | public string Password { get; set; }
15 |
16 | [Required]
17 | [Compare(nameof(Password), ErrorMessage = "Passwords do not match")]
18 | public string PasswordConfirm { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Shared/UserInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BlazorWithIdentity.Shared
6 | {
7 | public class UserInfo
8 | {
9 | public bool IsAuthenticated { get; set; }
10 | public string UserName { get; set; }
11 | public Dictionary ExposedClaims { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.Shared/WeatherForecast.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace BlazorWithIdentity.Shared
6 | {
7 | public class WeatherForecast
8 | {
9 | public DateTime Date { get; set; }
10 |
11 | public int TemperatureC { get; set; }
12 |
13 | public string Summary { get; set; }
14 |
15 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/template/BlazorWithIdentity.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26124.0
5 | MinimumVisualStudioVersion = 15.0.26124.0
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorWithIdentity.Server", "BlazorWithIdentity.Server\BlazorWithIdentity.Server.csproj", "{A707002F-F9D5-4133-9AC7-483418D94C7E}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorWithIdentity.Client", "BlazorWithIdentity.Client\BlazorWithIdentity.Client.csproj", "{8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlazorWithIdentity.Shared", "BlazorWithIdentity.Shared\BlazorWithIdentity.Shared.csproj", "{4506B124-94D1-4DA4-A81B-842A2F6B95E6}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|x64 = Debug|x64
16 | Debug|x86 = Debug|x86
17 | Release|Any CPU = Release|Any CPU
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(SolutionProperties) = preSolution
22 | HideSolutionNode = FALSE
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|x64.ActiveCfg = Debug|Any CPU
28 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|x64.Build.0 = Debug|Any CPU
29 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|x86.ActiveCfg = Debug|Any CPU
30 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Debug|x86.Build.0 = Debug|Any CPU
31 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|x64.ActiveCfg = Release|Any CPU
34 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|x64.Build.0 = Release|Any CPU
35 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|x86.ActiveCfg = Release|Any CPU
36 | {8BAEDA0D-7C16-40C7-BEF2-B77FA7F2AB0D}.Release|x86.Build.0 = Release|Any CPU
37 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|x64.ActiveCfg = Debug|Any CPU
40 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|x64.Build.0 = Debug|Any CPU
41 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|x86.ActiveCfg = Debug|Any CPU
42 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Debug|x86.Build.0 = Debug|Any CPU
43 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
44 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|Any CPU.Build.0 = Release|Any CPU
45 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|x64.ActiveCfg = Release|Any CPU
46 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|x64.Build.0 = Release|Any CPU
47 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|x86.ActiveCfg = Release|Any CPU
48 | {A707002F-F9D5-4133-9AC7-483418D94C7E}.Release|x86.Build.0 = Release|Any CPU
49 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|x64.ActiveCfg = Debug|Any CPU
52 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|x64.Build.0 = Debug|Any CPU
53 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|x86.ActiveCfg = Debug|Any CPU
54 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Debug|x86.Build.0 = Debug|Any CPU
55 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
56 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|Any CPU.Build.0 = Release|Any CPU
57 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|x64.ActiveCfg = Release|Any CPU
58 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|x64.Build.0 = Release|Any CPU
59 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|x86.ActiveCfg = Release|Any CPU
60 | {4506B124-94D1-4DA4-A81B-842A2F6B95E6}.Release|x86.Build.0 = Release|Any CPU
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/templatepack.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Template
5 | $(VersionSuffix)
6 | 2.0.0
7 | $(Version)-$(VersionSuffix)
8 | LICENSE.txt
9 | https://github.com/stavroskasidis/BlazorWithIdentity
10 | https://github.com/stavroskasidis/BlazorWithIdentity/blob/master/README.md
11 | BlazorWithIdentity.Template
12 | Blazor With Identity Template
13 | Stavros Kasidis (AkiraGTX)
14 | Templates to use when creating a blazor hosted application with microsoft's cookie based Identity.
15 | dotnet-new;templates;blazor;blazor-identity;blazor-cookie
16 |
17 | netstandard2.0
18 |
19 | true
20 | false
21 | content
22 | $(NoWarn);NU5128
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/uninstall.ps1:
--------------------------------------------------------------------------------
1 | dotnet new -u BlazorWithIdentity.Template
--------------------------------------------------------------------------------