;
15 |
16 | constructor(private authService: AuthService, private router: Router) {
17 | // schedule startup token refresh
18 | this.authService.startupTokenRefresh();
19 |
20 | this.isAuthenticated = this.authService.isAuthenticated();
21 | }
22 |
23 | private signOut(): void {
24 | this.authService.signOut();
25 | this.router.navigate(['/home']);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { JwtModule } from "@auth0/angular-jwt";
4 | import { HttpClientModule } from "@angular/common/http";
5 |
6 | import { MaterialModule } from './material.module';
7 | import { AppRoutingModule } from './app-routing.module';
8 | import { HomeModule } from './home/home.module';
9 | import { AccountModule } from './account/account.module';
10 | import { ApiModule } from './api/api.module';
11 |
12 | import { AppComponent } from './app.component';
13 |
14 | @NgModule({
15 | declarations: [
16 | AppComponent
17 | ],
18 | imports: [
19 | BrowserModule,
20 | HttpClientModule,
21 | AppRoutingModule,
22 | MaterialModule,
23 | HomeModule,
24 | AccountModule,
25 | ApiModule,
26 | JwtModule.forRoot({
27 | config: {
28 | tokenGetter: () => {
29 | return localStorage.getItem("access_token");
30 | },
31 | whitelistedDomains: ["localhost:5000", "localhost:5001"],
32 | blacklistedRoutes: ["localhost:5000/connect/token"]
33 | }
34 | })
35 | ],
36 | providers: [],
37 | bootstrap: [AppComponent]
38 | })
39 | export class AppModule { }
40 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/home/home-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | import { HomeComponent } from './home.component';
5 |
6 | const routes: Routes = [
7 | { path: 'home', component: HomeComponent }
8 | ];
9 |
10 | @NgModule({
11 | imports: [RouterModule.forRoot(routes)],
12 | exports: [RouterModule]
13 | })
14 | export class HomeRoutingModule { }
15 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/home/home.component.css:
--------------------------------------------------------------------------------
1 | mat-card-content div {
2 | margin-bottom: 10px;
3 | }
4 |
5 | mat-card-content div:last-child {
6 | margin-bottom: 0px;
7 | }
8 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/home/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
Home Component
3 |
4 |
5 |
6 | Project repository
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-home',
5 | templateUrl: './home.component.html',
6 | styleUrls: ['./home.component.css']
7 | })
8 | export class HomeComponent implements OnInit {
9 |
10 | constructor() { }
11 |
12 | ngOnInit() {
13 | }
14 |
15 | tiles = [
16 | { text: 'One', cols: 3, rows: 1, color: 'lightblue' },
17 | { text: 'Two', cols: 1, rows: 2, color: 'lightgreen' },
18 | { text: 'Three', cols: 1, rows: 1, color: 'lightpink' },
19 | { text: 'Four', cols: 2, rows: 1, color: '#DDBDF1' },
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 |
3 | import { HomeRoutingModule } from './home-routing.module';
4 | import { MaterialModule } from '../material.module';
5 |
6 | import { HomeComponent } from './home.component';
7 |
8 | @NgModule({
9 | declarations: [HomeComponent],
10 | imports: [
11 | HomeRoutingModule,
12 | MaterialModule
13 | ]
14 | })
15 | export class HomeModule { }
16 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/app/material.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
3 | import { MatButtonModule, MatCardModule, MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatProgressBarModule, MatToolbarModule } from '@angular/material';
4 |
5 |
6 | @NgModule({
7 | declarations: [],
8 | imports: [
9 | BrowserAnimationsModule,
10 | MatButtonModule,
11 | MatCardModule,
12 | MatIconModule,
13 | MatInputModule,
14 | MatListModule,
15 | MatMenuModule,
16 | MatProgressBarModule,
17 | MatToolbarModule
18 | ],
19 | exports: [
20 | BrowserAnimationsModule,
21 | MatButtonModule,
22 | MatCardModule,
23 | MatIconModule,
24 | MatInputModule,
25 | MatListModule,
26 | MatMenuModule,
27 | MatProgressBarModule,
28 | MatToolbarModule
29 | ]
30 | })
31 | export class MaterialModule { }
32 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marklaygo/Angular-IdentityServer-WebAPI/f7440e6b2e9fe9e0e32e1367579bc7f8cee8941a/src/Angular/ClientApp/src/assets/.gitkeep
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/assets/images/angular-white-transparent.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/assets/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marklaygo/Angular-IdentityServer-WebAPI/f7440e6b2e9fe9e0e32e1367579bc7f8cee8941a/src/Angular/ClientApp/src/assets/images/favicon.ico
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const globalEndPoint = {
6 | AuthEndPoint: 'http://localhost:5000',
7 | ApiEndPoint: 'http://localhost:5001',
8 | }
9 |
10 | export const environment = {
11 | production: false,
12 |
13 | // token
14 | TokenName: 'access_token',
15 | Token_Endpoint: globalEndPoint.AuthEndPoint + '/connect/token',
16 | UserInfo_Endpoint: globalEndPoint.AuthEndPoint + '/connect/userinfo',
17 | Client_Id: 'Angular',
18 | Grant_Type_Password: 'password',
19 | Grant_Type_RefreshToken: 'refresh_token',
20 | Scope: 'api1 offline_access openid profile accountApi',
21 |
22 | // account
23 | Register_Endpoint: globalEndPoint.AuthEndPoint + '/api/account/register',
24 | ChangePassword_Endpoint: globalEndPoint.AuthEndPoint + '/api/account/changepassword',
25 |
26 | // api
27 | NumbersApi_Endpoint: globalEndPoint.ApiEndPoint + '/api/numbers',
28 | };
29 |
30 | /*
31 | * For easier debugging in development mode, you can import the following file
32 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
33 | *
34 | * This import should be commented out in production mode because it will have a negative impact
35 | * on performance if an error is thrown.
36 | */
37 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI.
38 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marklaygo/Angular-IdentityServer-WebAPI/f7440e6b2e9fe9e0e32e1367579bc7f8cee8941a/src/Angular/ClientApp/src/favicon.ico
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err));
13 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
22 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
23 |
24 | /**
25 | * Web Animations `@angular/platform-browser/animations`
26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
28 | */
29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
30 |
31 | /**
32 | * By default, zone.js will patch all possible macroTask and DomEvents
33 | * user can disable parts of macroTask/DomEvents patch by setting following flags
34 | * because those flags need to be set before `zone.js` being loaded, and webpack
35 | * will put import in the top of bundle, so user need to create a separate file
36 | * in this directory (for example: zone-flags.ts), and put the following flags
37 | * into that file, and then add the following code before importing zone.js.
38 | * import './zone-flags.ts';
39 | *
40 | * The flags allowed in zone-flags.ts are listed here.
41 | *
42 | * The following flags will work for all browsers.
43 | *
44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
47 | *
48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
50 | *
51 | * (window as any).__Zone_enable_cross_context_check = true;
52 | *
53 | */
54 |
55 | /***************************************************************************************************
56 | * Zone JS is required by default for Angular itself.
57 | */
58 | import 'zone.js/dist/zone'; // Included with Angular CLI.
59 |
60 |
61 | /***************************************************************************************************
62 | * APPLICATION IMPORTS
63 | */
64 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | @import '@angular/material/prebuilt-themes/deeppurple-amber.css';
3 |
4 | * {
5 | margin: 0px;
6 | }
7 |
8 | body {
9 | background-color: #fafafa;
10 | color: rgba(0,0,0,.87);
11 | }
12 |
13 | .max-width {
14 | width: 100%;
15 | }
16 |
17 | .container {
18 | margin: 3%;
19 | }
20 |
21 | .form-val-hint {
22 | font-size: 75%;
23 | }
24 |
25 | .h-space {
26 | margin-bottom: 10px;
27 | }
28 |
29 | .failed-color {
30 | color: red;
31 | }
32 |
33 | .success-color {
34 | color: green;
35 | }
36 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/app",
5 | "types": []
6 | },
7 | "include": [
8 | "src/**/*.ts"
9 | ],
10 | "exclude": [
11 | "src/test.ts",
12 | "src/**/*.spec.ts"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "baseUrl": "./",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "downlevelIteration": true,
9 | "experimentalDecorators": true,
10 | "module": "esnext",
11 | "moduleResolution": "node",
12 | "importHelpers": true,
13 | "target": "es2015",
14 | "typeRoots": [
15 | "node_modules/@types"
16 | ],
17 | "lib": [
18 | "es2018",
19 | "dom"
20 | ]
21 | },
22 | "angularCompilerOptions": {
23 | "fullTemplateTypeCheck": true,
24 | "strictInjectionParameters": true
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./out-tsc/spec",
5 | "types": [
6 | "jasmine",
7 | "node"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src/Angular/ClientApp/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "tslint:recommended",
3 | "rules": {
4 | "array-type": false,
5 | "arrow-parens": false,
6 | "deprecation": {
7 | "severity": "warning"
8 | },
9 | "component-class-suffix": true,
10 | "contextual-lifecycle": true,
11 | "directive-class-suffix": true,
12 | "directive-selector": [
13 | true,
14 | "attribute",
15 | "app",
16 | "camelCase"
17 | ],
18 | "component-selector": [
19 | true,
20 | "element",
21 | "app",
22 | "kebab-case"
23 | ],
24 | "import-blacklist": [
25 | true,
26 | "rxjs/Rx"
27 | ],
28 | "interface-name": false,
29 | "max-classes-per-file": false,
30 | "max-line-length": [
31 | true,
32 | 140
33 | ],
34 | "member-access": false,
35 | "member-ordering": [
36 | true,
37 | {
38 | "order": [
39 | "static-field",
40 | "instance-field",
41 | "static-method",
42 | "instance-method"
43 | ]
44 | }
45 | ],
46 | "no-consecutive-blank-lines": false,
47 | "no-console": [
48 | true,
49 | "debug",
50 | "info",
51 | "time",
52 | "timeEnd",
53 | "trace"
54 | ],
55 | "no-empty": false,
56 | "no-inferrable-types": [
57 | true,
58 | "ignore-params"
59 | ],
60 | "no-non-null-assertion": true,
61 | "no-redundant-jsdoc": true,
62 | "no-switch-case-fall-through": true,
63 | "no-use-before-declare": true,
64 | "no-var-requires": false,
65 | "object-literal-key-quotes": [
66 | true,
67 | "as-needed"
68 | ],
69 | "object-literal-sort-keys": false,
70 | "ordered-imports": false,
71 | "quotemark": [
72 | true,
73 | "single"
74 | ],
75 | "trailing-comma": false,
76 | "no-conflicting-lifecycle": true,
77 | "no-host-metadata-property": true,
78 | "no-input-rename": true,
79 | "no-inputs-metadata-property": true,
80 | "no-output-native": true,
81 | "no-output-on-prefix": true,
82 | "no-output-rename": true,
83 | "no-outputs-metadata-property": true,
84 | "template-banana-in-box": true,
85 | "template-no-negated-async": true,
86 | "use-lifecycle-interface": true,
87 | "use-pipe-transform-interface": true
88 | },
89 | "rulesDirectory": [
90 | "codelyzer"
91 | ]
92 | }
--------------------------------------------------------------------------------
/src/Angular/Pages/Error.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ErrorModel
3 | @{
4 | ViewData["Title"] = "Error";
5 | }
6 |
7 | Error.
8 | An error occurred while processing your request.
9 |
10 | @if (Model.ShowRequestId)
11 | {
12 |
13 | Request ID: @Model.RequestId
14 |
15 | }
16 |
17 | Development Mode
18 |
19 | Swapping to Development environment will display more detailed information about the error that occurred.
20 |
21 |
22 | Development environment should not be enabled in deployed applications , as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development , and restarting the application.
23 |
24 |
--------------------------------------------------------------------------------
/src/Angular/Pages/Error.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Mvc;
7 | using Microsoft.AspNetCore.Mvc.RazorPages;
8 |
9 | namespace Angular.Pages
10 | {
11 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
12 | public class ErrorModel : PageModel
13 | {
14 | public string RequestId { get; set; }
15 |
16 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
17 |
18 | public void OnGet()
19 | {
20 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Angular/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using Angular
2 | @namespace Angular.Pages
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/src/Angular/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 |
11 | namespace Angular
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | CreateWebHostBuilder(args).Build().Run();
18 | }
19 |
20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
21 | WebHost.CreateDefaultBuilder(args)
22 | .UseStartup();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Angular/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:5002",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "Angular": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "http://localhost:5002",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/Angular/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.Mvc;
4 | using Microsoft.AspNetCore.SpaServices.AngularCli;
5 | using Microsoft.Extensions.Configuration;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | namespace Angular
9 | {
10 | public class Startup
11 | {
12 | public Startup(IConfiguration configuration)
13 | {
14 | Configuration = configuration;
15 | }
16 |
17 | public IConfiguration Configuration { get; }
18 |
19 | // This method gets called by the runtime. Use this method to add services to the container.
20 | public void ConfigureServices(IServiceCollection services)
21 | {
22 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
23 |
24 | // In production, the Angular files will be served from this directory
25 | services.AddSpaStaticFiles(configuration =>
26 | {
27 | configuration.RootPath = "ClientApp/dist";
28 | });
29 | }
30 |
31 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
32 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
33 | {
34 | if (env.IsDevelopment())
35 | {
36 | app.UseDeveloperExceptionPage();
37 | }
38 | else
39 | {
40 | app.UseExceptionHandler("/Error");
41 | }
42 |
43 | app.UseStaticFiles();
44 | app.UseSpaStaticFiles();
45 |
46 | app.UseMvc(routes =>
47 | {
48 | routes.MapRoute(
49 | name: "default",
50 | template: "{controller}/{action=Index}/{id?}");
51 | });
52 |
53 | app.UseSpa(spa =>
54 | {
55 | // To learn more about options for serving an Angular SPA from ASP.NET Core,
56 | // see https://go.microsoft.com/fwlink/?linkid=864501
57 |
58 | spa.Options.SourcePath = "ClientApp";
59 |
60 | if (env.IsDevelopment())
61 | {
62 | spa.UseAngularCliServer(npmScript: "start");
63 | }
64 | });
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Angular/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/Angular/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/src/IdentityServer/Config.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer4;
2 | using IdentityServer4.Models;
3 | using IdentityServer4.Test;
4 | using System.Collections.Generic;
5 |
6 | namespace IdentityServer
7 | {
8 | public static class Config
9 | {
10 | public static List GetUsers()
11 | {
12 | return new List
13 | {
14 | new TestUser
15 | {
16 | SubjectId = "1",
17 | Username = "alice@alice.com",
18 | Password = "password"
19 | }
20 | };
21 | }
22 |
23 | public static IEnumerable GetIdentityResources()
24 | {
25 | return new IdentityResource[]
26 | {
27 | new IdentityResources.OpenId(),
28 | new IdentityResources.Profile()
29 | };
30 | }
31 |
32 | public static IEnumerable GetApis()
33 | {
34 | return new ApiResource[]
35 | {
36 | new ApiResource("api1", "webApi"),
37 | new ApiResource("accountApi", "AccountApi")
38 | };
39 | }
40 |
41 | public static IEnumerable GetClients()
42 | {
43 | return new Client[]
44 | {
45 | new Client
46 | {
47 | ClientId = "Angular",
48 | AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
49 | RequireClientSecret = false,
50 | AllowAccessTokensViaBrowser = true,
51 | AccessTokenLifetime = 300,
52 | AllowOfflineAccess = true,
53 | AllowedScopes =
54 | {
55 | IdentityServerConstants.StandardScopes.OpenId,
56 | IdentityServerConstants.StandardScopes.Profile,
57 | "api1",
58 | "accountApi"
59 | }
60 | }
61 | };
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/src/IdentityServer/Controllers/AccountController.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer.Models;
2 | using IdentityServer.Models.Account;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Identity;
5 | using Microsoft.AspNetCore.Mvc;
6 | using System;
7 | using System.Collections.Generic;
8 | using System.Linq;
9 | using System.Threading.Tasks;
10 |
11 | namespace IdentityServer.Controllers
12 | {
13 | [Route("api/[controller]")]
14 | public class AccountController : ControllerBase
15 | {
16 | #region Fields
17 |
18 | private readonly UserManager _userManager;
19 | private readonly IUserClaimsPrincipalFactory _claimsFactory;
20 |
21 | #endregion
22 |
23 | #region Constructor
24 |
25 | public AccountController(
26 | UserManager userManager,
27 | IUserClaimsPrincipalFactory claimsFactory)
28 | {
29 | _userManager = userManager;
30 | _claimsFactory = claimsFactory;
31 | }
32 |
33 | #endregion
34 |
35 | #region Methods
36 |
37 | [HttpPost("Register")]
38 | public async Task Register([FromBody]RegisterViewModel model)
39 | {
40 | if (ModelState.IsValid)
41 | {
42 | var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
43 | var result = await _userManager.CreateAsync(user, model.Password);
44 |
45 | return new JsonResult(result);
46 | }
47 |
48 | return BadRequest();
49 | }
50 |
51 | [HttpPost("ChangePassword")]
52 | [Authorize(AuthenticationSchemes = "Bearer")]
53 | public async Task ChangePassword([FromBody]ChangePasswordViewModel model)
54 | {
55 | if (ModelState.IsValid)
56 | {
57 | var user = await _userManager.FindByEmailAsync(model.Email);
58 | if (user != null)
59 | {
60 | var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
61 | return new JsonResult(result);
62 | }
63 | }
64 |
65 | return BadRequest();
66 | }
67 |
68 | #endregion
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/IdentityServer/Data/ApplicationDbContext.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer.Models;
2 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
3 | using Microsoft.EntityFrameworkCore;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 |
9 | namespace IdentityServer.Data
10 | {
11 | public class ApplicationDbContext : IdentityDbContext
12 | {
13 | public ApplicationDbContext(DbContextOptions options)
14 | : base(options)
15 | {
16 | }
17 |
18 | protected override void OnModelCreating(ModelBuilder builder)
19 | {
20 | base.OnModelCreating(builder);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/IdentityServer/IdentityProfileService.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel;
2 | using IdentityServer.Models;
3 | using IdentityServer4.Extensions;
4 | using IdentityServer4.Models;
5 | using IdentityServer4.Services;
6 | using Microsoft.AspNetCore.Identity;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 | using System.Security.Claims;
11 | using System.Threading.Tasks;
12 |
13 | namespace IdentityServer
14 | {
15 | public class IdentityProfileService : IProfileService
16 | {
17 | #region Fields
18 |
19 | private readonly IUserClaimsPrincipalFactory _claimsFactory;
20 | private readonly UserManager _userManager;
21 |
22 | #endregion
23 |
24 | #region Constructor
25 |
26 | public IdentityProfileService(
27 | IUserClaimsPrincipalFactory claimsFactory,
28 | UserManager userManager)
29 | {
30 | _claimsFactory = claimsFactory;
31 | _userManager = userManager;
32 | }
33 |
34 | #endregion
35 |
36 | #region Method
37 |
38 | public async Task GetProfileDataAsync(ProfileDataRequestContext context)
39 | {
40 | var subjectId = context.Subject.GetSubjectId();
41 | var user = await _userManager.FindByIdAsync(subjectId);
42 | var principal = await _claimsFactory.CreateAsync(user);
43 | var claims = principal.Claims.ToList();
44 |
45 | // test role
46 | claims.Add(new Claim(JwtClaimTypes.Role, "test_role"));
47 |
48 | context.IssuedClaims = claims;
49 | }
50 |
51 | public async Task IsActiveAsync(IsActiveContext context)
52 | {
53 | var subjectId = context.Subject.GetSubjectId();
54 | var user = await _userManager.FindByIdAsync(subjectId);
55 | context.IsActive = user != null;
56 | }
57 |
58 | #endregion
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/IdentityServer/IdentityServer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/IdentityServer/Migrations/20190713034352_initial.Designer.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using IdentityServer.Data;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Migrations;
8 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
9 |
10 | namespace IdentityServer.Migrations
11 | {
12 | [DbContext(typeof(ApplicationDbContext))]
13 | [Migration("20190713034352_initial")]
14 | partial class initial
15 | {
16 | protected override void BuildTargetModel(ModelBuilder modelBuilder)
17 | {
18 | #pragma warning disable 612, 618
19 | modelBuilder
20 | .HasAnnotation("ProductVersion", "2.1.11-servicing-32099")
21 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
23 |
24 | modelBuilder.Entity("IdentityServer.Models.ApplicationUser", b =>
25 | {
26 | b.Property("Id")
27 | .ValueGeneratedOnAdd();
28 |
29 | b.Property("AccessFailedCount");
30 |
31 | b.Property("ConcurrencyStamp")
32 | .IsConcurrencyToken();
33 |
34 | b.Property("Email")
35 | .HasMaxLength(256);
36 |
37 | b.Property("EmailConfirmed");
38 |
39 | b.Property("LockoutEnabled");
40 |
41 | b.Property("LockoutEnd");
42 |
43 | b.Property("NormalizedEmail")
44 | .HasMaxLength(256);
45 |
46 | b.Property("NormalizedUserName")
47 | .HasMaxLength(256);
48 |
49 | b.Property("PasswordHash");
50 |
51 | b.Property("PhoneNumber");
52 |
53 | b.Property("PhoneNumberConfirmed");
54 |
55 | b.Property("SecurityStamp");
56 |
57 | b.Property("TwoFactorEnabled");
58 |
59 | b.Property("UserName")
60 | .HasMaxLength(256);
61 |
62 | b.HasKey("Id");
63 |
64 | b.HasIndex("NormalizedEmail")
65 | .HasName("EmailIndex");
66 |
67 | b.HasIndex("NormalizedUserName")
68 | .IsUnique()
69 | .HasName("UserNameIndex")
70 | .HasFilter("[NormalizedUserName] IS NOT NULL");
71 |
72 | b.ToTable("AspNetUsers");
73 | });
74 |
75 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
76 | {
77 | b.Property("Id")
78 | .ValueGeneratedOnAdd();
79 |
80 | b.Property("ConcurrencyStamp")
81 | .IsConcurrencyToken();
82 |
83 | b.Property("Name")
84 | .HasMaxLength(256);
85 |
86 | b.Property("NormalizedName")
87 | .HasMaxLength(256);
88 |
89 | b.HasKey("Id");
90 |
91 | b.HasIndex("NormalizedName")
92 | .IsUnique()
93 | .HasName("RoleNameIndex")
94 | .HasFilter("[NormalizedName] IS NOT NULL");
95 |
96 | b.ToTable("AspNetRoles");
97 | });
98 |
99 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
100 | {
101 | b.Property("Id")
102 | .ValueGeneratedOnAdd()
103 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
104 |
105 | b.Property("ClaimType");
106 |
107 | b.Property("ClaimValue");
108 |
109 | b.Property("RoleId")
110 | .IsRequired();
111 |
112 | b.HasKey("Id");
113 |
114 | b.HasIndex("RoleId");
115 |
116 | b.ToTable("AspNetRoleClaims");
117 | });
118 |
119 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
120 | {
121 | b.Property("Id")
122 | .ValueGeneratedOnAdd()
123 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
124 |
125 | b.Property("ClaimType");
126 |
127 | b.Property("ClaimValue");
128 |
129 | b.Property("UserId")
130 | .IsRequired();
131 |
132 | b.HasKey("Id");
133 |
134 | b.HasIndex("UserId");
135 |
136 | b.ToTable("AspNetUserClaims");
137 | });
138 |
139 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
140 | {
141 | b.Property("LoginProvider");
142 |
143 | b.Property("ProviderKey");
144 |
145 | b.Property("ProviderDisplayName");
146 |
147 | b.Property("UserId")
148 | .IsRequired();
149 |
150 | b.HasKey("LoginProvider", "ProviderKey");
151 |
152 | b.HasIndex("UserId");
153 |
154 | b.ToTable("AspNetUserLogins");
155 | });
156 |
157 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
158 | {
159 | b.Property("UserId");
160 |
161 | b.Property("RoleId");
162 |
163 | b.HasKey("UserId", "RoleId");
164 |
165 | b.HasIndex("RoleId");
166 |
167 | b.ToTable("AspNetUserRoles");
168 | });
169 |
170 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
171 | {
172 | b.Property("UserId");
173 |
174 | b.Property("LoginProvider");
175 |
176 | b.Property("Name");
177 |
178 | b.Property("Value");
179 |
180 | b.HasKey("UserId", "LoginProvider", "Name");
181 |
182 | b.ToTable("AspNetUserTokens");
183 | });
184 |
185 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
186 | {
187 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
188 | .WithMany()
189 | .HasForeignKey("RoleId")
190 | .OnDelete(DeleteBehavior.Cascade);
191 | });
192 |
193 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
194 | {
195 | b.HasOne("IdentityServer.Models.ApplicationUser")
196 | .WithMany()
197 | .HasForeignKey("UserId")
198 | .OnDelete(DeleteBehavior.Cascade);
199 | });
200 |
201 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
202 | {
203 | b.HasOne("IdentityServer.Models.ApplicationUser")
204 | .WithMany()
205 | .HasForeignKey("UserId")
206 | .OnDelete(DeleteBehavior.Cascade);
207 | });
208 |
209 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
210 | {
211 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
212 | .WithMany()
213 | .HasForeignKey("RoleId")
214 | .OnDelete(DeleteBehavior.Cascade);
215 |
216 | b.HasOne("IdentityServer.Models.ApplicationUser")
217 | .WithMany()
218 | .HasForeignKey("UserId")
219 | .OnDelete(DeleteBehavior.Cascade);
220 | });
221 |
222 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
223 | {
224 | b.HasOne("IdentityServer.Models.ApplicationUser")
225 | .WithMany()
226 | .HasForeignKey("UserId")
227 | .OnDelete(DeleteBehavior.Cascade);
228 | });
229 | #pragma warning restore 612, 618
230 | }
231 | }
232 | }
233 |
--------------------------------------------------------------------------------
/src/IdentityServer/Migrations/20190713034352_initial.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.EntityFrameworkCore.Metadata;
3 | using Microsoft.EntityFrameworkCore.Migrations;
4 |
5 | namespace IdentityServer.Migrations
6 | {
7 | public partial class initial : Migration
8 | {
9 | protected override void Up(MigrationBuilder migrationBuilder)
10 | {
11 | migrationBuilder.CreateTable(
12 | name: "AspNetRoles",
13 | columns: table => new
14 | {
15 | Id = table.Column(nullable: false),
16 | Name = table.Column(maxLength: 256, nullable: true),
17 | NormalizedName = table.Column(maxLength: 256, nullable: true),
18 | ConcurrencyStamp = table.Column(nullable: true)
19 | },
20 | constraints: table =>
21 | {
22 | table.PrimaryKey("PK_AspNetRoles", x => x.Id);
23 | });
24 |
25 | migrationBuilder.CreateTable(
26 | name: "AspNetUsers",
27 | columns: table => new
28 | {
29 | Id = table.Column(nullable: false),
30 | UserName = table.Column(maxLength: 256, nullable: true),
31 | NormalizedUserName = table.Column(maxLength: 256, nullable: true),
32 | Email = table.Column(maxLength: 256, nullable: true),
33 | NormalizedEmail = table.Column(maxLength: 256, nullable: true),
34 | EmailConfirmed = table.Column(nullable: false),
35 | PasswordHash = table.Column(nullable: true),
36 | SecurityStamp = table.Column(nullable: true),
37 | ConcurrencyStamp = table.Column(nullable: true),
38 | PhoneNumber = table.Column(nullable: true),
39 | PhoneNumberConfirmed = table.Column(nullable: false),
40 | TwoFactorEnabled = table.Column(nullable: false),
41 | LockoutEnd = table.Column(nullable: true),
42 | LockoutEnabled = table.Column(nullable: false),
43 | AccessFailedCount = table.Column(nullable: false)
44 | },
45 | constraints: table =>
46 | {
47 | table.PrimaryKey("PK_AspNetUsers", x => x.Id);
48 | });
49 |
50 | migrationBuilder.CreateTable(
51 | name: "AspNetRoleClaims",
52 | columns: table => new
53 | {
54 | Id = table.Column(nullable: false)
55 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
56 | RoleId = table.Column(nullable: false),
57 | ClaimType = table.Column(nullable: true),
58 | ClaimValue = table.Column(nullable: true)
59 | },
60 | constraints: table =>
61 | {
62 | table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
63 | table.ForeignKey(
64 | name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
65 | column: x => x.RoleId,
66 | principalTable: "AspNetRoles",
67 | principalColumn: "Id",
68 | onDelete: ReferentialAction.Cascade);
69 | });
70 |
71 | migrationBuilder.CreateTable(
72 | name: "AspNetUserClaims",
73 | columns: table => new
74 | {
75 | Id = table.Column(nullable: false)
76 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
77 | UserId = table.Column(nullable: false),
78 | ClaimType = table.Column(nullable: true),
79 | ClaimValue = table.Column(nullable: true)
80 | },
81 | constraints: table =>
82 | {
83 | table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
84 | table.ForeignKey(
85 | name: "FK_AspNetUserClaims_AspNetUsers_UserId",
86 | column: x => x.UserId,
87 | principalTable: "AspNetUsers",
88 | principalColumn: "Id",
89 | onDelete: ReferentialAction.Cascade);
90 | });
91 |
92 | migrationBuilder.CreateTable(
93 | name: "AspNetUserLogins",
94 | columns: table => new
95 | {
96 | LoginProvider = table.Column(nullable: false),
97 | ProviderKey = table.Column(nullable: false),
98 | ProviderDisplayName = table.Column(nullable: true),
99 | UserId = table.Column(nullable: false)
100 | },
101 | constraints: table =>
102 | {
103 | table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
104 | table.ForeignKey(
105 | name: "FK_AspNetUserLogins_AspNetUsers_UserId",
106 | column: x => x.UserId,
107 | principalTable: "AspNetUsers",
108 | principalColumn: "Id",
109 | onDelete: ReferentialAction.Cascade);
110 | });
111 |
112 | migrationBuilder.CreateTable(
113 | name: "AspNetUserRoles",
114 | columns: table => new
115 | {
116 | UserId = table.Column(nullable: false),
117 | RoleId = table.Column(nullable: false)
118 | },
119 | constraints: table =>
120 | {
121 | table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
122 | table.ForeignKey(
123 | name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
124 | column: x => x.RoleId,
125 | principalTable: "AspNetRoles",
126 | principalColumn: "Id",
127 | onDelete: ReferentialAction.Cascade);
128 | table.ForeignKey(
129 | name: "FK_AspNetUserRoles_AspNetUsers_UserId",
130 | column: x => x.UserId,
131 | principalTable: "AspNetUsers",
132 | principalColumn: "Id",
133 | onDelete: ReferentialAction.Cascade);
134 | });
135 |
136 | migrationBuilder.CreateTable(
137 | name: "AspNetUserTokens",
138 | columns: table => new
139 | {
140 | UserId = table.Column(nullable: false),
141 | LoginProvider = table.Column(nullable: false),
142 | Name = table.Column(nullable: false),
143 | Value = table.Column(nullable: true)
144 | },
145 | constraints: table =>
146 | {
147 | table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
148 | table.ForeignKey(
149 | name: "FK_AspNetUserTokens_AspNetUsers_UserId",
150 | column: x => x.UserId,
151 | principalTable: "AspNetUsers",
152 | principalColumn: "Id",
153 | onDelete: ReferentialAction.Cascade);
154 | });
155 |
156 | migrationBuilder.CreateIndex(
157 | name: "IX_AspNetRoleClaims_RoleId",
158 | table: "AspNetRoleClaims",
159 | column: "RoleId");
160 |
161 | migrationBuilder.CreateIndex(
162 | name: "RoleNameIndex",
163 | table: "AspNetRoles",
164 | column: "NormalizedName",
165 | unique: true,
166 | filter: "[NormalizedName] IS NOT NULL");
167 |
168 | migrationBuilder.CreateIndex(
169 | name: "IX_AspNetUserClaims_UserId",
170 | table: "AspNetUserClaims",
171 | column: "UserId");
172 |
173 | migrationBuilder.CreateIndex(
174 | name: "IX_AspNetUserLogins_UserId",
175 | table: "AspNetUserLogins",
176 | column: "UserId");
177 |
178 | migrationBuilder.CreateIndex(
179 | name: "IX_AspNetUserRoles_RoleId",
180 | table: "AspNetUserRoles",
181 | column: "RoleId");
182 |
183 | migrationBuilder.CreateIndex(
184 | name: "EmailIndex",
185 | table: "AspNetUsers",
186 | column: "NormalizedEmail");
187 |
188 | migrationBuilder.CreateIndex(
189 | name: "UserNameIndex",
190 | table: "AspNetUsers",
191 | column: "NormalizedUserName",
192 | unique: true,
193 | filter: "[NormalizedUserName] IS NOT NULL");
194 | }
195 |
196 | protected override void Down(MigrationBuilder migrationBuilder)
197 | {
198 | migrationBuilder.DropTable(
199 | name: "AspNetRoleClaims");
200 |
201 | migrationBuilder.DropTable(
202 | name: "AspNetUserClaims");
203 |
204 | migrationBuilder.DropTable(
205 | name: "AspNetUserLogins");
206 |
207 | migrationBuilder.DropTable(
208 | name: "AspNetUserRoles");
209 |
210 | migrationBuilder.DropTable(
211 | name: "AspNetUserTokens");
212 |
213 | migrationBuilder.DropTable(
214 | name: "AspNetRoles");
215 |
216 | migrationBuilder.DropTable(
217 | name: "AspNetUsers");
218 | }
219 | }
220 | }
221 |
--------------------------------------------------------------------------------
/src/IdentityServer/Migrations/ApplicationDbContextModelSnapshot.cs:
--------------------------------------------------------------------------------
1 | //
2 | using System;
3 | using IdentityServer.Data;
4 | using Microsoft.EntityFrameworkCore;
5 | using Microsoft.EntityFrameworkCore.Infrastructure;
6 | using Microsoft.EntityFrameworkCore.Metadata;
7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
8 |
9 | namespace IdentityServer.Migrations
10 | {
11 | [DbContext(typeof(ApplicationDbContext))]
12 | partial class ApplicationDbContextModelSnapshot : ModelSnapshot
13 | {
14 | protected override void BuildModel(ModelBuilder modelBuilder)
15 | {
16 | #pragma warning disable 612, 618
17 | modelBuilder
18 | .HasAnnotation("ProductVersion", "2.1.11-servicing-32099")
19 | .HasAnnotation("Relational:MaxIdentifierLength", 128)
20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
21 |
22 | modelBuilder.Entity("IdentityServer.Models.ApplicationUser", b =>
23 | {
24 | b.Property("Id")
25 | .ValueGeneratedOnAdd();
26 |
27 | b.Property("AccessFailedCount");
28 |
29 | b.Property("ConcurrencyStamp")
30 | .IsConcurrencyToken();
31 |
32 | b.Property("Email")
33 | .HasMaxLength(256);
34 |
35 | b.Property("EmailConfirmed");
36 |
37 | b.Property("LockoutEnabled");
38 |
39 | b.Property("LockoutEnd");
40 |
41 | b.Property("NormalizedEmail")
42 | .HasMaxLength(256);
43 |
44 | b.Property("NormalizedUserName")
45 | .HasMaxLength(256);
46 |
47 | b.Property("PasswordHash");
48 |
49 | b.Property("PhoneNumber");
50 |
51 | b.Property("PhoneNumberConfirmed");
52 |
53 | b.Property("SecurityStamp");
54 |
55 | b.Property("TwoFactorEnabled");
56 |
57 | b.Property("UserName")
58 | .HasMaxLength(256);
59 |
60 | b.HasKey("Id");
61 |
62 | b.HasIndex("NormalizedEmail")
63 | .HasName("EmailIndex");
64 |
65 | b.HasIndex("NormalizedUserName")
66 | .IsUnique()
67 | .HasName("UserNameIndex")
68 | .HasFilter("[NormalizedUserName] IS NOT NULL");
69 |
70 | b.ToTable("AspNetUsers");
71 | });
72 |
73 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
74 | {
75 | b.Property("Id")
76 | .ValueGeneratedOnAdd();
77 |
78 | b.Property("ConcurrencyStamp")
79 | .IsConcurrencyToken();
80 |
81 | b.Property("Name")
82 | .HasMaxLength(256);
83 |
84 | b.Property("NormalizedName")
85 | .HasMaxLength(256);
86 |
87 | b.HasKey("Id");
88 |
89 | b.HasIndex("NormalizedName")
90 | .IsUnique()
91 | .HasName("RoleNameIndex")
92 | .HasFilter("[NormalizedName] IS NOT NULL");
93 |
94 | b.ToTable("AspNetRoles");
95 | });
96 |
97 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
98 | {
99 | b.Property("Id")
100 | .ValueGeneratedOnAdd()
101 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
102 |
103 | b.Property("ClaimType");
104 |
105 | b.Property("ClaimValue");
106 |
107 | b.Property("RoleId")
108 | .IsRequired();
109 |
110 | b.HasKey("Id");
111 |
112 | b.HasIndex("RoleId");
113 |
114 | b.ToTable("AspNetRoleClaims");
115 | });
116 |
117 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
118 | {
119 | b.Property("Id")
120 | .ValueGeneratedOnAdd()
121 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
122 |
123 | b.Property("ClaimType");
124 |
125 | b.Property("ClaimValue");
126 |
127 | b.Property("UserId")
128 | .IsRequired();
129 |
130 | b.HasKey("Id");
131 |
132 | b.HasIndex("UserId");
133 |
134 | b.ToTable("AspNetUserClaims");
135 | });
136 |
137 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
138 | {
139 | b.Property("LoginProvider");
140 |
141 | b.Property("ProviderKey");
142 |
143 | b.Property("ProviderDisplayName");
144 |
145 | b.Property("UserId")
146 | .IsRequired();
147 |
148 | b.HasKey("LoginProvider", "ProviderKey");
149 |
150 | b.HasIndex("UserId");
151 |
152 | b.ToTable("AspNetUserLogins");
153 | });
154 |
155 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
156 | {
157 | b.Property("UserId");
158 |
159 | b.Property("RoleId");
160 |
161 | b.HasKey("UserId", "RoleId");
162 |
163 | b.HasIndex("RoleId");
164 |
165 | b.ToTable("AspNetUserRoles");
166 | });
167 |
168 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
169 | {
170 | b.Property("UserId");
171 |
172 | b.Property("LoginProvider");
173 |
174 | b.Property("Name");
175 |
176 | b.Property("Value");
177 |
178 | b.HasKey("UserId", "LoginProvider", "Name");
179 |
180 | b.ToTable("AspNetUserTokens");
181 | });
182 |
183 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
184 | {
185 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
186 | .WithMany()
187 | .HasForeignKey("RoleId")
188 | .OnDelete(DeleteBehavior.Cascade);
189 | });
190 |
191 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
192 | {
193 | b.HasOne("IdentityServer.Models.ApplicationUser")
194 | .WithMany()
195 | .HasForeignKey("UserId")
196 | .OnDelete(DeleteBehavior.Cascade);
197 | });
198 |
199 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
200 | {
201 | b.HasOne("IdentityServer.Models.ApplicationUser")
202 | .WithMany()
203 | .HasForeignKey("UserId")
204 | .OnDelete(DeleteBehavior.Cascade);
205 | });
206 |
207 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
208 | {
209 | b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
210 | .WithMany()
211 | .HasForeignKey("RoleId")
212 | .OnDelete(DeleteBehavior.Cascade);
213 |
214 | b.HasOne("IdentityServer.Models.ApplicationUser")
215 | .WithMany()
216 | .HasForeignKey("UserId")
217 | .OnDelete(DeleteBehavior.Cascade);
218 | });
219 |
220 | modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
221 | {
222 | b.HasOne("IdentityServer.Models.ApplicationUser")
223 | .WithMany()
224 | .HasForeignKey("UserId")
225 | .OnDelete(DeleteBehavior.Cascade);
226 | });
227 | #pragma warning restore 612, 618
228 | }
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/src/IdentityServer/Models/Account/ChangePasswordViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace IdentityServer.Models.Account
8 | {
9 | public class ChangePasswordViewModel
10 | {
11 | [Required]
12 | [DataType(DataType.EmailAddress)]
13 | public string Email { get; set; }
14 |
15 | [Required]
16 | [DataType(DataType.Password)]
17 | public string OldPassword { get; set; }
18 |
19 | [Required]
20 | [DataType(DataType.Password)]
21 | public string NewPassword { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/IdentityServer/Models/Account/RegisterViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.DataAnnotations;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 | namespace IdentityServer.Models.Account
8 | {
9 | public class RegisterViewModel
10 | {
11 | [Required]
12 | [EmailAddress]
13 | public string Email { get; set; }
14 |
15 | [Required]
16 | [DataType(DataType.Password)]
17 | public string Password { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/IdentityServer/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 IdentityServer.Models
8 | {
9 | public class ApplicationUser : IdentityUser
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/IdentityServer/Program.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Serilog;
4 | using Serilog.Events;
5 | using Serilog.Sinks.SystemConsole.Themes;
6 | using System;
7 |
8 | namespace IdentityServer
9 | {
10 | public class Program
11 | {
12 | public static void Main(string[] args)
13 | {
14 | Console.Title = "IdentityServer4";
15 |
16 | CreateWebHostBuilder(args).Build().Run();
17 | }
18 |
19 | public static IWebHostBuilder CreateWebHostBuilder(string[] args)
20 | {
21 | return WebHost.CreateDefaultBuilder(args)
22 | .UseStartup()
23 | .UseSerilog((context, configuration) =>
24 | {
25 | configuration
26 | .MinimumLevel.Debug()
27 | .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
28 | .MinimumLevel.Override("System", LogEventLevel.Warning)
29 | .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
30 | .Enrich.FromLogContext()
31 | .WriteTo.File(@"identityserver4_log.txt")
32 | .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate);
33 | });
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/src/IdentityServer/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:5000",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": false,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "SelfHost": {
19 | "commandName": "Project",
20 | "environmentVariables": {
21 | "ASPNETCORE_ENVIRONMENT": "Development"
22 | },
23 | "applicationUrl": "http://localhost:5000"
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/IdentityServer/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using IdentityServer.Data;
4 | using IdentityServer.Models;
5 | using IdentityServer4.Services;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.AspNetCore.Identity;
9 | using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
10 | using Microsoft.EntityFrameworkCore;
11 | using Microsoft.Extensions.Configuration;
12 | using Microsoft.Extensions.DependencyInjection;
13 | using Microsoft.IdentityModel.Tokens;
14 |
15 | namespace IdentityServer
16 | {
17 | public class Startup
18 | {
19 | public IConfiguration Configuration { get; }
20 | public IHostingEnvironment Environment { get; }
21 |
22 | public Startup(IConfiguration configuration, IHostingEnvironment environment)
23 | {
24 | Configuration = configuration;
25 | Environment = environment;
26 | }
27 |
28 | public void ConfigureServices(IServiceCollection services)
29 | {
30 | // add db context
31 | services.AddDbContext(options =>
32 | //options.UseInMemoryDatabase(databaseName: "IdentityServer4"));
33 | options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
34 |
35 | // add identity
36 | services.AddIdentity()
37 | .AddEntityFrameworkStores()
38 | .AddDefaultTokenProviders();
39 |
40 | // configure password requirements
41 | services.Configure(options =>
42 | {
43 | options.Password.RequireDigit = false;
44 | options.Password.RequiredLength = 4;
45 | options.Password.RequireNonAlphanumeric = false;
46 | options.Password.RequireUppercase = false;
47 | options.Password.RequireLowercase = false;
48 | });
49 |
50 | // add mvc
51 | services.AddMvcCore()
52 | .AddAuthorization()
53 | .AddJsonFormatters();
54 |
55 | // dependency injection
56 | services.AddTransient();
57 |
58 | // add identityserver4
59 | var builder = services.AddIdentityServer()
60 | .AddInMemoryIdentityResources(Config.GetIdentityResources())
61 | .AddInMemoryApiResources(Config.GetApis())
62 | .AddInMemoryClients(Config.GetClients())
63 | //.AddTestUsers(Config.GetUsers())
64 | .AddAspNetIdentity()
65 | .AddProfileService();
66 |
67 |
68 | services.AddAuthentication("Bearer")
69 | .AddJwtBearer("Bearer", options =>
70 | {
71 | options.Authority = "http://localhost:5000";
72 | options.RequireHttpsMetadata = false;
73 | options.Audience = "accountApi";
74 | options.TokenValidationParameters = new TokenValidationParameters()
75 | {
76 | ClockSkew = TimeSpan.FromMinutes(0)
77 | };
78 | });
79 |
80 | // add cors
81 | services.AddCors(options =>
82 | {
83 | // this defines a CORS policy called "default"
84 | options.AddPolicy("default", policy =>
85 | {
86 | policy.WithOrigins("http://localhost:4200")
87 | .AllowAnyHeader()
88 | .AllowAnyMethod();
89 | });
90 | });
91 |
92 | if (Environment.IsDevelopment())
93 | {
94 | builder.AddDeveloperSigningCredential();
95 | }
96 | else
97 | {
98 | throw new Exception("need to configure key material");
99 | }
100 | }
101 |
102 | public void Configure(IApplicationBuilder app, ApplicationDbContext context)
103 | {
104 | if (Environment.IsDevelopment())
105 | {
106 | app.UseDeveloperExceptionPage();
107 | }
108 |
109 | app.UseCors("default");
110 | app.UseIdentityServer();
111 | app.UseAuthentication();
112 | app.UseMvc();
113 |
114 | // quick way to apply migration and test user
115 | try
116 | {
117 | //var context = app.ApplicationServices.GetService();
118 |
119 | // apply migration
120 | context.Database.Migrate();
121 |
122 | // delete all users
123 | context.Users.RemoveRange(context.Users.ToList());
124 | context.SaveChanges();
125 |
126 | // add test user
127 | var user = new ApplicationUser()
128 | {
129 | UserName = "test@test.com",
130 | NormalizedUserName = "TEST@TEST.COM",
131 | Email = "test@test.com",
132 | NormalizedEmail = "TEST@TEST.COM",
133 | EmailConfirmed = true,
134 | LockoutEnabled = false,
135 | SecurityStamp = Guid.NewGuid().ToString()
136 | };
137 |
138 | if (!context.Users.Any(u => u.UserName == user.UserName))
139 | {
140 | var passwordHasher = new PasswordHasher();
141 | var hashed = passwordHasher.HashPassword(user, "11234");
142 | user.PasswordHash = hashed;
143 | var userStore = new UserStore(context);
144 | userStore.CreateAsync(user);
145 | }
146 | }
147 | catch (Exception)
148 | {
149 | throw;
150 | }
151 | }
152 | }
153 | }
--------------------------------------------------------------------------------
/src/IdentityServer/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=IdentityServer4;Trusted_Connection=True;MultipleActiveResultSets=true"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/WebAPI/Controllers/NumbersController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Mvc;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using WebAPI.Data;
8 |
9 | namespace WebAPI.Controllers
10 | {
11 | [Authorize]
12 | [Route("api/[controller]")]
13 | [ApiController]
14 | public class NumbersController : ControllerBase
15 | {
16 | // GET api/numbers
17 | [HttpGet]
18 | public IActionResult Get()
19 | {
20 | return new JsonResult(NumberService.GetAllNumbers());
21 | }
22 |
23 | // POST api/numbers
24 | [HttpPost]
25 | public IActionResult Post([FromBody]int value)
26 | {
27 | NumberService.Add(value);
28 | return new NoContentResult();
29 | }
30 |
31 | // POST api/numbers/delete
32 | [HttpPost("Delete")]
33 | public IActionResult Delete([FromBody]int id)
34 | {
35 | if (NumberService.GetNumberById(id) == null)
36 | {
37 | return BadRequest();
38 | }
39 |
40 | NumberService.Delete(id);
41 |
42 | return new NoContentResult();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/WebAPI/Data/NumberService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using WebAPI.Models;
6 |
7 | namespace WebAPI.Data
8 | {
9 | // static service to test api
10 | public static class NumberService
11 | {
12 | private static List Numbers = new List();
13 | private static int id = 1;
14 |
15 | public static void Initialize()
16 | {
17 | Random r = new Random();
18 |
19 | for (int i = 0; i < 5; i++)
20 | {
21 | Numbers.Add(new Number { Id = id, Value = r.Next(1, 999) });
22 | id++;
23 | }
24 | }
25 |
26 | public static List GetAllNumbers()
27 | {
28 | return Numbers;
29 | }
30 |
31 | public static Number GetNumberById(int id)
32 | {
33 | return Numbers.SingleOrDefault(x => x.Id == id);
34 | }
35 |
36 | public static void Add(int value)
37 | {
38 | var n = new Number { Id = id, Value = value };
39 | id++;
40 | Numbers.Add(n);
41 | }
42 |
43 | public static void Delete(int id)
44 | {
45 | var number = GetNumberById(id);
46 | Numbers.Remove(number);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/WebAPI/Models/Number.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | namespace WebAPI.Models
7 | {
8 | public class Number
9 | {
10 | public int Id { get; set; }
11 | public int Value { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/WebAPI/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.Logging;
10 |
11 | namespace WebAPI
12 | {
13 | public class Program
14 | {
15 | public static void Main(string[] args)
16 | {
17 | CreateWebHostBuilder(args).Build().Run();
18 | }
19 |
20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
21 | WebHost.CreateDefaultBuilder(args)
22 | .UseStartup();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/WebAPI/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json.schemastore.org/launchsettings.json",
3 | "iisSettings": {
4 | "windowsAuthentication": false,
5 | "anonymousAuthentication": true,
6 | "iisExpress": {
7 | "applicationUrl": "http://localhost:5001",
8 | "sslPort": 0
9 | }
10 | },
11 | "profiles": {
12 | "IIS Express": {
13 | "commandName": "IISExpress",
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "WebAPI": {
19 | "commandName": "Project",
20 | "applicationUrl": "http://localhost:5001",
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | }
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/WebAPI/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Mvc;
8 | using Microsoft.Extensions.Configuration;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Logging;
11 | using Microsoft.Extensions.Options;
12 | using Microsoft.IdentityModel.Tokens;
13 | using WebAPI.Data;
14 |
15 | namespace WebAPI
16 | {
17 | public class Startup
18 | {
19 | public Startup(IConfiguration configuration)
20 | {
21 | Configuration = configuration;
22 | }
23 |
24 | public IConfiguration Configuration { get; }
25 |
26 | // This method gets called by the runtime. Use this method to add services to the container.
27 | public void ConfigureServices(IServiceCollection services)
28 | {
29 | services.AddMvcCore()
30 | .AddAuthorization()
31 | .AddJsonFormatters();
32 |
33 | services.AddAuthentication("Bearer")
34 | .AddJwtBearer("Bearer", options =>
35 | {
36 | options.Authority = "http://localhost:5000";
37 | options.RequireHttpsMetadata = false;
38 | options.Audience = "api1";
39 | options.TokenValidationParameters = new TokenValidationParameters()
40 | {
41 | ClockSkew = TimeSpan.FromMinutes(0)
42 | };
43 | });
44 |
45 | services.AddCors(options =>
46 | {
47 | options.AddPolicy("default", policy =>
48 | {
49 | policy.WithOrigins("http://localhost:4200")
50 | .AllowAnyHeader()
51 | .AllowAnyMethod();
52 | });
53 | });
54 | }
55 |
56 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
57 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
58 | {
59 | if (env.IsDevelopment())
60 | {
61 | app.UseDeveloperExceptionPage();
62 | }
63 |
64 | app.UseCors("default");
65 | app.UseAuthentication();
66 | app.UseMvc();
67 |
68 | NumberService.Initialize();
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/WebAPI/WebAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/WebAPI/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/WebAPI/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------