├── src
├── Views
│ ├── _ViewImports.cshtml
│ ├── _ViewStart.cshtml
│ ├── Home
│ │ └── Index.cshtml
│ └── Shared
│ │ └── _Layout.cshtml
├── client
│ ├── .browserslistrc
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── vue.config.js
│ ├── babel.config.js
│ ├── src
│ │ ├── main.js
│ │ ├── views
│ │ │ ├── Home.vue
│ │ │ ├── Colors.vue
│ │ │ └── Login.vue
│ │ ├── services
│ │ │ └── http.js
│ │ ├── router
│ │ │ └── index.js
│ │ ├── App.vue
│ │ └── store
│ │ │ └── index.js
│ ├── .gitignore
│ ├── README.md
│ ├── .eslintrc.js
│ └── package.json
├── appsettings.Development.json
├── appsettings.json
├── libman.json
├── Models
│ ├── AuthRequestModel.cs
│ └── AuthResultModel.cs
├── Controllers
│ ├── HomeController.cs
│ ├── ColorsController.cs
│ └── AuthController.cs
├── VueJwt.csproj
├── Program.cs
├── Properties
│ └── launchSettings.json
├── VueJwt.sln
├── Security
│ └── TokenSecurity.cs
└── Startup.cs
├── .gitignore
└── readme.md
/src/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/src/client/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/wwwroot/app
2 | bin
3 | obj
4 | **/wwwroot/lib
5 | .suo
6 | .vs
--------------------------------------------------------------------------------
/src/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shawnwildermuth/vuejwt/HEAD/src/client/public/favicon.ico
--------------------------------------------------------------------------------
/src/client/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | outputDir: "..\\wwwroot\\app",
3 | filenameHashing: false
4 | }
--------------------------------------------------------------------------------
/src/client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Vue with JWT (in ASP.NET Core)
2 |
3 | This is an example project to show how to secure a routing Vue 3 project is with a JWT token.
--------------------------------------------------------------------------------
/src/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | @section Scripts {
2 |
3 |
4 | }
5 |
--------------------------------------------------------------------------------
/src/client/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 |
6 | createApp(App).use(store).use(router).mount('#theApp')
7 |
--------------------------------------------------------------------------------
/src/client/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 | Vue Auth Example
3 | This page should be fine.
4 |
5 |
6 |
11 |
--------------------------------------------------------------------------------
/src/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/src/client/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/src/libman.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "defaultProvider": "cdnjs",
4 | "libraries": [
5 | {
6 | "library": "jquery@3.5.1",
7 | "destination": "wwwroot/lib/jquery/"
8 | },
9 | {
10 | "provider": "unpkg",
11 | "library": "bootstrap@4.5.2",
12 | "destination": "wwwroot/lib/bootstrap/"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/src/Models/AuthRequestModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VueJwt.Models
8 | {
9 | public class AuthRequestModel
10 | {
11 | public string Username { get; set; }
12 | public string Password { get; set; }
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/client/src/services/http.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import store from "@/store";
3 |
4 |
5 | export default function createHttp(secured = true) {
6 |
7 | if (secured) {
8 | return axios.create({
9 | headers: { "Authorization": `bearer ${store.state.token}` }
10 | });
11 | } else {
12 | return axios.create();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Models/AuthResultModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace VueJwt.Models
8 | {
9 | public class AuthResultModel
10 | {
11 | public bool Success { get; set; }
12 | public string Token { get; set; }
13 | public DateTime Expiration { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Mvc;
7 |
8 | namespace VueJwt.Controllers
9 | {
10 | public class HomeController : Controller
11 | {
12 | public ActionResult Index()
13 | {
14 | return View();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/VueJwt.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/client/README.md:
--------------------------------------------------------------------------------
1 | # client
2 |
3 | ## Project setup
4 | ```
5 | npm install
6 | ```
7 |
8 | ### Compiles and hot-reloads for development
9 | ```
10 | npm run serve
11 | ```
12 |
13 | ### Compiles and minifies for production
14 | ```
15 | npm run build
16 | ```
17 |
18 | ### Lints and fixes files
19 | ```
20 | npm run lint
21 | ```
22 |
23 | ### Customize configuration
24 | See [Configuration Reference](https://cli.vuejs.org/config/).
25 |
--------------------------------------------------------------------------------
/src/client/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | 'extends': [
7 | 'plugin:vue/vue3-essential',
8 | 'eslint:recommended'
9 | ],
10 | parserOptions: {
11 | parser: 'babel-eslint'
12 | },
13 | rules: {
14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Controllers/ColorsController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Authorization;
7 | using Microsoft.AspNetCore.Mvc;
8 |
9 | namespace VueJwt.Controllers
10 | {
11 | [Route("api/[controller]")]
12 | [ApiController]
13 | [Authorize]
14 | public class ColorsController
15 | {
16 | [HttpGet]
17 | public ActionResult Get()
18 | {
19 | return new[] { "Blue", "Red", "Green" };
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/client/src/views/Colors.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Colors
4 |
You'd have to login to get here....
5 |
8 |
9 |
10 |
11 |
27 |
--------------------------------------------------------------------------------
/src/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Hosting;
6 | using Microsoft.Extensions.Configuration;
7 | using Microsoft.Extensions.Hosting;
8 | using Microsoft.Extensions.Logging;
9 |
10 | namespace VueJwt
11 | {
12 | public class Program
13 | {
14 | public static void Main(string[] args)
15 | {
16 | CreateHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IHostBuilder CreateHostBuilder(string[] args) =>
20 | Host.CreateDefaultBuilder(args)
21 | .ConfigureWebHostDefaults(webBuilder =>
22 | {
23 | webBuilder.UseStartup();
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:8080",
7 | "sslPort": 0
8 | }
9 | },
10 | "$schema": "http://json.schemastore.org/launchsettings.json",
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "launchBrowser": true,
15 | "environmentVariables": {
16 | "ASPNETCORE_ENVIRONMENT": "Development"
17 | }
18 | },
19 | "VueJwt": {
20 | "commandName": "Project",
21 | "launchBrowser": true,
22 | "launchUrl": "weatherforecast",
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development"
25 | },
26 | "applicationUrl": "https://localhost:5001;http://localhost:5000"
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/src/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "watch": "vue-cli-service build --watch --mode=development",
9 | "lint": "vue-cli-service lint"
10 | },
11 | "dependencies": {
12 | "axios": "^0.20.0",
13 | "core-js": "^3.6.5",
14 | "vue": "^3.0.0",
15 | "vue-router": "^4.0.0-0",
16 | "vuex": "^4.0.0-0"
17 | },
18 | "devDependencies": {
19 | "@vue/cli-plugin-babel": "~4.5.0",
20 | "@vue/cli-plugin-eslint": "~4.5.0",
21 | "@vue/cli-plugin-router": "~4.5.0",
22 | "@vue/cli-plugin-vuex": "~4.5.0",
23 | "@vue/cli-service": "~4.5.0",
24 | "@vue/compiler-sfc": "^3.0.0",
25 | "babel-eslint": "^10.1.0",
26 | "eslint": "^6.7.2",
27 | "eslint-plugin-vue": "^7.0.0-0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/client/src/router/index.js:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHashHistory } from 'vue-router'
2 | import Home from '../views/Home.vue'
3 | import Colors from '../views/Colors.vue'
4 | import Login from '../views/Login.vue'
5 | import store from "@/store";
6 |
7 | const authGuard = (to, from, next) => {
8 | if (store.getters.isAuthenticated) {
9 | next();
10 | } else {
11 | next("/login")
12 | }
13 | };
14 |
15 | const routes = [
16 | {
17 | path: '/',
18 | name: 'Home',
19 | component: Home
20 | },
21 | {
22 | path: '/colors',
23 | name: 'Colors',
24 | component: Colors,
25 | beforeEnter: authGuard
26 | },
27 | {
28 | path: '/login',
29 | name: 'Login',
30 | component: Login
31 | },
32 | ]
33 |
34 | const router = createRouter({
35 | history: createWebHashHistory(),
36 | routes
37 | })
38 |
39 | // Clear the error on every navigation
40 | router.afterEach(() => {
41 | store.commit("clearError");
42 | });
43 |
44 |
45 | export default router
46 |
--------------------------------------------------------------------------------
/src/VueJwt.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30523.141
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VueJwt", "VueJwt.csproj", "{5A8C35E8-B5F7-4374-8378-2DDDB16538F6}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {5A8C35E8-B5F7-4374-8378-2DDDB16538F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {5A8C35E8-B5F7-4374-8378-2DDDB16538F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {5A8C35E8-B5F7-4374-8378-2DDDB16538F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {5A8C35E8-B5F7-4374-8378-2DDDB16538F6}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {CAAFFF23-B891-4C6A-B4D4-5CDF92E4929D}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/src/client/src/views/Login.vue:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/client/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
Home |
6 |
Colors
7 |
8 | |
9 | Login
10 |
11 |
12 | |
13 | Logout
14 |
15 |
16 |
Loading...
17 |
{{ error }}
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/Controllers/AuthController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IdentityModel.Tokens.Jwt;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using Microsoft.AspNetCore.Mvc;
8 | using VueJwt.Models;
9 | using VueJwt.Security;
10 |
11 | namespace VueJwt.Controllers
12 | {
13 | [Route("api/[controller]")]
14 | [ApiController]
15 | public class AuthController : ControllerBase
16 | {
17 | [HttpPost]
18 | public ActionResult Post([FromBody] AuthRequestModel model)
19 | {
20 | // NEVER DO THIS, JUST SHOWING THE EXAMPLE
21 | if (model.Username == "shawn@wildermuth.com"
22 | && model.Password == "P@ssw0rd!")
23 | {
24 | var result = new AuthResultModel()
25 | {
26 | Success = true
27 | };
28 |
29 | // Never do this either, hardcoded strings
30 | var token = TokenSecurity.GenerateJwt(model.Username);
31 | result.Token = new JwtSecurityTokenHandler().WriteToken(token);
32 | result.Expiration = token.ValidTo;
33 |
34 | return Created("", result);
35 |
36 | }
37 |
38 | return BadRequest("Unknown failure");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
27 |
28 |
29 |
30 |
31 | @RenderBody()
32 |
33 |
34 |
35 |
36 |
37 |
38 | @RenderSection("Scripts", false)
39 |
40 |
--------------------------------------------------------------------------------
/src/Security/TokenSecurity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IdentityModel.Tokens.Jwt;
4 | using System.Linq;
5 | using System.Security.Claims;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Microsoft.IdentityModel.Tokens;
9 |
10 | namespace VueJwt.Security
11 | {
12 | public static class TokenSecurity
13 | {
14 | // Hard coded security keys
15 | // DO NOT DO THIS, SERIOUSLY
16 | // JUST AN EXAMPLE
17 | public static readonly string SIGNING_KEY = "FOOBARQUUX_FOOBARQUUX_FOOBARQUUX_FOOBARQUUX";
18 | public static readonly string ISSUER = "localhost";
19 | public static readonly string AUDIENCE = "All";
20 |
21 | public static JwtSecurityToken GenerateJwt(string email)
22 | {
23 | var claims = new List()
24 | {
25 | new Claim(JwtRegisteredClaimNames.Sub, email),
26 | new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
27 | new Claim(JwtRegisteredClaimNames.UniqueName, email)
28 | };
29 |
30 | var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SIGNING_KEY));
31 | var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512);
32 |
33 | var token = new JwtSecurityToken(
34 | ISSUER,
35 | AUDIENCE,
36 | claims,
37 | expires: DateTime.Now.AddMinutes(20),
38 | signingCredentials: creds);
39 |
40 | return token;
41 |
42 | }
43 |
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/client/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore } from 'vuex'
2 | import createHttp from "@/services/http";
3 | import router from "@/router";
4 |
5 | export default createStore({
6 | state: {
7 | colors: [],
8 | token: "",
9 | expiration: Date.now(),
10 | isBusy: false,
11 | error: ""
12 | },
13 | mutations: {
14 | setColors: (state, colors) => state.colors = colors,
15 | setBusy: (state) => state.isBusy = true,
16 | clearBusy: (state) => state.isBusy = false,
17 | setError: (state, error) => state.error = error,
18 | clearError: (state) => state.error = "",
19 | setToken: (state, model) => {
20 | state.token = model.token;
21 | state.expiration = new Date(model.expiration)
22 | },
23 | clearToken: (state) => {
24 | state.token = "";
25 | state.expiration = Date.now();
26 | }
27 | },
28 | getters: {
29 | isAuthenticated: (state) => state.token.length > 0 && state.expiration > Date.now()
30 | },
31 | actions: {
32 | loadColors: async ({ commit }) => {
33 | try {
34 | commit("setBusy");
35 | commit("clearError");
36 | const http = createHttp(); // secured
37 | const colors = await http.get("/api/colors");
38 | commit("setColors", colors.data);
39 | } catch {
40 | commit("setError", "Failed getting colors");
41 | } finally {
42 | commit("clearBusy");
43 | }
44 | },
45 | login: async ({ commit }, model) => {
46 | try {
47 | commit("setBusy");
48 | commit("clearError");
49 | const http = createHttp(false); // unsecured
50 | const result = await http.post("/api/auth", model);
51 | if (result.data.success) {
52 | commit("setToken", result.data);
53 | router.push("/");
54 | }
55 | else {
56 | commit("setError", "Authentication Failed");
57 | }
58 | } catch {
59 | commit("setError", "Failed to login");
60 | } finally {
61 | commit("clearBusy");
62 | }
63 | },
64 | logout: ({ commit }) => {
65 | commit("clearToken");
66 | router.push("/");
67 | }
68 | }
69 | })
70 |
--------------------------------------------------------------------------------
/src/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Authentication.JwtBearer;
7 | using Microsoft.AspNetCore.Authorization;
8 | using Microsoft.AspNetCore.Builder;
9 | using Microsoft.AspNetCore.Hosting;
10 | using Microsoft.AspNetCore.HttpsPolicy;
11 | using Microsoft.AspNetCore.Mvc;
12 | using Microsoft.Extensions.Configuration;
13 | using Microsoft.Extensions.DependencyInjection;
14 | using Microsoft.Extensions.Hosting;
15 | using Microsoft.Extensions.Logging;
16 | using Microsoft.IdentityModel.Tokens;
17 | using VueJwt.Security;
18 |
19 | namespace VueJwt
20 | {
21 | public class Startup
22 | {
23 | public Startup(IConfiguration configuration)
24 | {
25 | Configuration = configuration;
26 | }
27 |
28 | public IConfiguration Configuration { get; }
29 |
30 | // This method gets called by the runtime. Use this method to add services to the container.
31 | public void ConfigureServices(IServiceCollection services)
32 | {
33 | services.AddAuthorization(cfg =>
34 | {
35 | var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme);
36 | defaultAuthorizationPolicyBuilder =
37 | defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();
38 | cfg.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
39 | });
40 |
41 | services.AddAuthentication(cfg => {
42 | cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
43 | cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
44 | }).AddJwtBearer(cfg =>
45 | {
46 | cfg.TokenValidationParameters = new TokenValidationParameters()
47 | {
48 | ValidIssuer = TokenSecurity.ISSUER,
49 | ValidAudience = TokenSecurity.AUDIENCE,
50 | IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenSecurity.SIGNING_KEY)),
51 | };
52 | });
53 |
54 | services.AddControllersWithViews();
55 | }
56 |
57 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
58 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
59 | {
60 | if (env.IsDevelopment())
61 | {
62 | app.UseDeveloperExceptionPage();
63 | }
64 |
65 | app.UseStaticFiles();
66 |
67 | app.UseRouting();
68 |
69 | app.UseAuthorization();
70 |
71 | app.UseEndpoints(endpoints =>
72 | {
73 | endpoints.MapControllers();
74 | endpoints.MapDefaultControllerRoute();
75 | });
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------