()
60 | //.AddConfigurationStore(options =>
61 | //{
62 | // options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
63 | // sql => sql.MigrationsAssembly(assembly));
64 | //})
65 | //.AddOperationalStore(options =>
66 | //{
67 | // options.ConfigureDbContext = b => b.UseSqlServer(connectionString,
68 | // sql => sql.MigrationsAssembly(assembly));
69 | //})
70 | //.AddSigningCredential(certificate);
71 | .AddInMemoryApiResources(Configuration.GetApis())
72 | .AddInMemoryIdentityResources(Configuration.GetIdentityResources())
73 | .AddInMemoryClients(Configuration.GetClients())
74 | .AddDeveloperSigningCredential();
75 |
76 | services.AddAuthentication()
77 | .AddFacebook(config => {
78 | config.AppId = "3396617443742614";
79 | config.AppSecret = "secret";
80 | });
81 |
82 | services.AddControllersWithViews();
83 | }
84 |
85 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
86 | {
87 | if (env.IsDevelopment())
88 | {
89 | app.UseDeveloperExceptionPage();
90 | }
91 |
92 | app.UseRouting();
93 |
94 | app.UseIdentityServer();
95 |
96 | if(_env.IsDevelopment())
97 | {
98 | app.UseCookiePolicy(new CookiePolicyOptions()
99 | {
100 | MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax
101 | });
102 | }
103 |
104 | app.UseEndpoints(endpoints =>
105 | {
106 | endpoints.MapDefaultControllerRoute();
107 | });
108 | }
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/IdentityServer/Views/Auth/ExternalRegister.cshtml:
--------------------------------------------------------------------------------
1 | @model ExternalRegisterViewModel
2 |
3 |
--------------------------------------------------------------------------------
/IdentityServer/Views/Auth/Login.cshtml:
--------------------------------------------------------------------------------
1 | @model LoginViewModel
2 |
3 | Sign In With
4 |
15 |
16 |
30 |
--------------------------------------------------------------------------------
/IdentityServer/Views/Auth/Register.cshtml:
--------------------------------------------------------------------------------
1 | @model RegisterViewModel
2 |
3 |
24 |
25 | Back to Login
--------------------------------------------------------------------------------
/IdentityServer/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using IdentityServer.Controllers
2 | @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
--------------------------------------------------------------------------------
/IdentityServer/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/IdentityServer/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "ConnectionStrings": {
3 | "DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=IdentityServer4Tutorial;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
4 | },
5 | "Logging": {
6 | "LogLevel": {
7 | "Default": "Information",
8 | "Microsoft": "Warning",
9 | "Microsoft.Hosting.Lifetime": "Information"
10 | }
11 | },
12 | "AllowedHosts": "*"
13 | }
14 |
--------------------------------------------------------------------------------
/IdentityServer/db-scripts.txt:
--------------------------------------------------------------------------------
1 | dotnet ef migrations add InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb
2 | dotnet ef migrations add InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb
3 |
4 | dotnet ef migrations add -c AppDbContext -o Data/Migrations/AppMigrations
5 | dotnet ef database update -c AppDbContext
6 |
7 | dotnet ef database update -c PersistedGrantDbContext
8 | dotnet ef database update -c ConfigurationDbContext
--------------------------------------------------------------------------------
/IdentityServer/tempkey.rsa:
--------------------------------------------------------------------------------
1 | {"KeyId":"MKYnjQ_a1EfAdUkVD7ToVA","Parameters":{"D":"u/GbkcvjWsPNtMymodf6SMuhzGM/f7vEf3pOaZlNmivSoXH6kxiNVPA5bLcsN+ni5Ybq1V0GJsKTwgd9IE+xHkIAoR8EMY7etxADr/azgLTGzuB8nRXL5LrcSeA43j0VHxqSKwYqO3TguVihUmIGC2l+7SOGd5BsZNXRZtbz4NbNOkVE3OXcplK1Rm7nANmBkpE7jScQzA8Vm3RqjA7tobvax11QFcIqk2wfisEiI15liJbKmBKioGLesT/djrVq28qKZWnIWCsBkWdwoSGlYn8pwPMU9UO7FHo4PSh9q+sdfk4CewrYAGl6op4Yj94zxXhqY+67K1PX1bSWLGYIIQ==","DP":"O2vWpsL68mSdSfeK+EeczqhyMVeNgmNwetsdiO7TqBs8uY/rKpeOnuKKxclBYcmleqT3zdajHlCjo02C6aXKMjzBo5UNJcJ/llIrHY7En4pADkTYQSPor8jEASDW0ptmF3r8TA0LR+Wv7u2Xe7yFLu2Paf4KbkS3myyK5WaEYsk=","DQ":"QmXWpltIURiagLtMGoNjpTRFSh+kJsqVp9nnioHShta9+MHC4ICmYngx6DzgIRVMcW7xEcJZYimIFAogNg9GTuVJH/E0/f+ml9a6gQ5W/t0w4MmlRX66dZbLhblvAxBbr2WN2cPR8EWZ9iQiyIEePZEINATNhmFP7xwPfF1BTks=","Exponent":"AQAB","InverseQ":"fsl3OoFlL7k25As4qO0tUx881qyoog2h5KMRlfrMyLrwVlygQSnlmN/dUHDSILu2Y93EBMSS3B76paxh2VNhpw2TZykM+TtrZL+laiU6SE/thtUGUS/Ylgx9y6tsDHIV8EzKxgUYkWTlFOrEElVnu86EEYK3Bu5eSAs+w5JykEs=","Modulus":"01ixZ7ujifVsulyKYKF9Wat/fZRzjkOPG3CL4Iw+Ntxjb6mJUSdTBsV7yYjXjI3yFOqr0loCwfHZb40EE1A7hPNzK3etbAA2SIZa365ZJjv7qJobeCgZjvJnr5UvL+xEBAEzS3vS4u9KmI0+AF243SxtmQxrpkfqTl+cL4wDMmkffGBFlAigufR80NXR5sTejEHAQzjCTPR1518ssNX9OM8t1QHGxGwtp5OUZDSx0DZuCGuvHfEk5eYIEqNfhNEtZnvPmEEqrv6Adweaf4XI2kSrFlBfVjE2DXzeTvy8Kd9wSw6jE8gj+mfo9CcYKpLSqZrxUSetz0RfAnK2sLF1OQ==","P":"4q0Akz8lc69pD6Dx/Yj8k6iDg3QIQRoW+1hHldmu7CKkdbpVY/8vASZZpkvN285HeEIT8xouNRqNjyB1K1e8K7ve3Xg7huEGoNaYs6zTNkhafKVR7P0bS00+bw4gHk/hSYINk01L8yPR0OA1EUkHYfh3FR8epCMigltI7MTW878=","Q":"7rAEcKTkDDOOgMpioOLko/QSO2kqHjqPvX2nSc9YSpvn5Zjl+91w5kTlOlsGh2nFmHIOar0/CrLmDvGN5a2UGoFwiTH16BwJQrQ/hecItXtMoIHyFholRZ+3KEWaQi9qlum0apMECAaL/sszceS2eLkZP43jXvMn7WiF6R819Qc="}}
--------------------------------------------------------------------------------
/JavascriptClient/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 | namespace JavascriptClient.Controllers
4 | {
5 | public class HomeController : Controller
6 | {
7 | public IActionResult Index()
8 | {
9 | return View();
10 | }
11 |
12 | public IActionResult SignIn()
13 | {
14 | return View();
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/JavascriptClient/JavascriptClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/JavascriptClient/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 JavascriptClient
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 |
--------------------------------------------------------------------------------
/JavascriptClient/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:65505",
7 | "sslPort": 44345
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "JavascriptClient": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/JavascriptClient/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.Http;
8 | using Microsoft.Extensions.DependencyInjection;
9 | using Microsoft.Extensions.Hosting;
10 |
11 | namespace JavascriptClient
12 | {
13 | public class Startup
14 | {
15 | public void ConfigureServices(IServiceCollection services)
16 | {
17 | services.AddControllersWithViews()
18 | .AddRazorRuntimeCompilation();
19 | }
20 |
21 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
22 | {
23 | if (env.IsDevelopment())
24 | {
25 | app.UseDeveloperExceptionPage();
26 | }
27 |
28 | app.UseStaticFiles();
29 |
30 | app.UseRouting();
31 |
32 | app.UseEndpoints(endpoints =>
33 | {
34 | endpoints.MapDefaultControllerRoute();
35 | });
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/JavascriptClient/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 |
2 | Home Page
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/JavascriptClient/Views/Home/SignIn.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/JavascriptClient/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/JavascriptClient/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/JavascriptClient/wwwroot/js-old/sign-in-callback.js:
--------------------------------------------------------------------------------
1 | var extractTokens = function (address) {
2 | var returnValue = address.split('#')[1];
3 | var values = returnValue.split('&');
4 |
5 | for (var i = 0; i < values.length; i++) {
6 | var v = values[i];
7 | var kvPair = v.split('=');
8 | localStorage.setItem(kvPair[0], kvPair[1]);
9 | }
10 |
11 | window.location.href = '/home/index';
12 | }
13 |
14 |
15 | extractTokens(window.location.href);
--------------------------------------------------------------------------------
/JavascriptClient/wwwroot/js-old/sign-in.js:
--------------------------------------------------------------------------------
1 | var createState = function () {
2 | return "SessionValueMakeItABitLongerasdfhjsadoighasdifjdsalkhrfakwelyrosdpiufghasidkgewr";
3 | };
4 |
5 | var createNonce = function () {
6 | return "NonceValuedsafliudsayatroiewewryie123";
7 | };
8 |
9 | var signIn = function () {
10 | var redirectUri = "https://localhost:44345/Home/SignIn";
11 | var responseType = "id_token token";
12 | var scope = "openid ApiOne";
13 | var authUrl =
14 | "/connect/authorize/callback" +
15 | "?client_id=client_id_js" +
16 | "&redirect_uri=" + encodeURIComponent(redirectUri) +
17 | "&response_type=" + encodeURIComponent(responseType) +
18 | "&scope=" + encodeURIComponent(scope) +
19 | "&nonce="+ createNonce() +
20 | "&state="+ createState();
21 |
22 | var returnUrl = encodeURIComponent(authUrl);
23 |
24 | window.location.href = "https://localhost:44305/Auth/Login?ReturnUrl=" + returnUrl;
25 | }
26 |
27 |
28 |
--------------------------------------------------------------------------------
/JavascriptClient/wwwroot/main.js:
--------------------------------------------------------------------------------
1 | var config = {
2 | userStore: new Oidc.WebStorageStateStore({ store: window.localStorage }),
3 | authority: "https://localhost:44305/",
4 | client_id: "client_id_js",
5 | redirect_uri: "https://localhost:44345/Home/SignIn",
6 | post_logout_redirect_uri: "https://localhost:44345/Home/Index",
7 | response_type: "code",
8 | scope: "openid rc.scope ApiOne ApiTwo"
9 | };
10 |
11 | var userManager = new Oidc.UserManager(config);
12 |
13 | var signIn = function () {
14 | userManager.signinRedirect();
15 | };
16 |
17 | var signOut = function() {
18 | userManager.signoutRedirect();
19 | };
20 |
21 | userManager.getUser().then(user => {
22 | console.log("user:", user);
23 | if (user) {
24 | axios.defaults.headers.common["Authorization"] = "Bearer " + user.access_token;
25 | }
26 | });
27 |
28 | var callApi = function () {
29 | axios.get("https://localhost:44337/secret")
30 | .then(res => {
31 | console.log(res);
32 | });
33 | };
34 |
35 | var refreshing = false;
36 |
37 | axios.interceptors.response.use(
38 | function (response) { return response; },
39 | function (error) {
40 | console.log("axios error:", error.response);
41 |
42 | var axiosConfig = error.response.config;
43 |
44 | //if error response is 401 try to refresh token
45 | if (error.response.status === 401) {
46 | console.log("axios error 401");
47 |
48 | // if already refreshing don't make another request
49 | if (!refreshing) {
50 | console.log("starting token refresh");
51 | refreshing = true;
52 |
53 | // do the refresh
54 | return userManager.signinSilent().then(user => {
55 | console.log("new user:", user);
56 | //update the http request and client
57 | axios.defaults.headers.common["Authorization"] = "Bearer " + user.access_token;
58 | axiosConfig.headers["Authorization"] = "Bearer " + user.access_token;
59 | //retry the http request
60 | return axios(axiosConfig);
61 | });
62 | }
63 | }
64 |
65 | return Promise.reject(error);
66 | });
--------------------------------------------------------------------------------
/MvcClient/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel.Client;
2 | using Microsoft.AspNetCore.Authentication;
3 | using Microsoft.AspNetCore.Authorization;
4 | using Microsoft.AspNetCore.Mvc;
5 | using System.IdentityModel.Tokens.Jwt;
6 | using System.Linq;
7 | using System.Net.Http;
8 | using System.Threading.Tasks;
9 |
10 | namespace MvcClient.Controllers
11 | {
12 | public class HomeController : Controller
13 | {
14 | private readonly IHttpClientFactory _httpClientFactory;
15 |
16 | public HomeController(IHttpClientFactory httpClientFactory)
17 | {
18 | _httpClientFactory = httpClientFactory;
19 | }
20 |
21 | public IActionResult Index()
22 | {
23 | return View();
24 | }
25 |
26 | [Authorize]
27 | public async Task Secret()
28 | {
29 | var accessToken = await HttpContext.GetTokenAsync("access_token");
30 | var idToken = await HttpContext.GetTokenAsync("id_token");
31 | var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
32 |
33 | var claims = User.Claims.ToList();
34 | var _accessToken = new JwtSecurityTokenHandler().ReadJwtToken(accessToken);
35 | var _idToken = new JwtSecurityTokenHandler().ReadJwtToken(idToken);
36 |
37 | var result = await GetSecret(accessToken);
38 |
39 | await RefreshAccessToken();
40 |
41 | return View();
42 | }
43 |
44 | public IActionResult Logout()
45 | {
46 | return SignOut("Cookie", "oidc");
47 | }
48 |
49 | public async Task GetSecret(string accessToken)
50 | {
51 | var apiClient = _httpClientFactory.CreateClient();
52 |
53 | apiClient.SetBearerToken(accessToken);
54 |
55 | var response = await apiClient.GetAsync("https://localhost:44337/secret");
56 |
57 | var content = await response.Content.ReadAsStringAsync();
58 |
59 | return content;
60 | }
61 |
62 | private async Task RefreshAccessToken()
63 | {
64 | var serverClient = _httpClientFactory.CreateClient();
65 | var discoveryDocument = await serverClient.GetDiscoveryDocumentAsync("https://localhost:44305/");
66 |
67 | var accessToken = await HttpContext.GetTokenAsync("access_token");
68 | var idToken = await HttpContext.GetTokenAsync("id_token");
69 | var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
70 | var refreshTokenClient = _httpClientFactory.CreateClient();
71 |
72 | var tokenResponse = await refreshTokenClient.RequestRefreshTokenAsync(
73 | new RefreshTokenRequest
74 | {
75 | Address = discoveryDocument.TokenEndpoint,
76 | RefreshToken = refreshToken,
77 | ClientId = "client_id_mvc",
78 | ClientSecret = "client_secret_mvc"
79 | });
80 |
81 | var authInfo = await HttpContext.AuthenticateAsync("Cookie");
82 |
83 | authInfo.Properties.UpdateTokenValue("access_token", tokenResponse.AccessToken);
84 | authInfo.Properties.UpdateTokenValue("id_token", tokenResponse.IdentityToken);
85 | authInfo.Properties.UpdateTokenValue("refresh_token", tokenResponse.RefreshToken);
86 |
87 | await HttpContext.SignInAsync("Cookie", authInfo.Principal, authInfo.Properties);
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/MvcClient/MvcClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/MvcClient/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 MvcClient
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 |
--------------------------------------------------------------------------------
/MvcClient/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:49386",
7 | "sslPort": 44322
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "MvcClient": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MvcClient/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Authentication;
6 | using Microsoft.AspNetCore.Builder;
7 | using Microsoft.AspNetCore.Hosting;
8 | using Microsoft.AspNetCore.Http;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using Microsoft.Extensions.Hosting;
11 |
12 | namespace MvcClient
13 | {
14 | public class Startup
15 | {
16 | public void ConfigureServices(IServiceCollection services)
17 | {
18 | services.AddAuthentication(config => {
19 | config.DefaultScheme = "Cookie";
20 | config.DefaultChallengeScheme = "oidc";
21 | })
22 | .AddCookie("Cookie")
23 | .AddOpenIdConnect("oidc", config => {
24 | config.Authority = "https://localhost:44305/";
25 | config.ClientId = "client_id_mvc";
26 | config.ClientSecret = "client_secret_mvc";
27 | config.SaveTokens = true;
28 | config.ResponseType = "code";
29 | config.SignedOutCallbackPath = "/Home/Index";
30 |
31 | // configure cookie claim mapping
32 | config.ClaimActions.DeleteClaim("amr");
33 | config.ClaimActions.DeleteClaim("s_hash");
34 | config.ClaimActions.MapUniqueJsonKey("RawCoding.Grandma", "rc.garndma");
35 |
36 | // two trips to load claims in to the cookie
37 | // but the id token is smaller !
38 | config.GetClaimsFromUserInfoEndpoint = true;
39 |
40 | // configure scope
41 | config.Scope.Clear();
42 | config.Scope.Add("openid");
43 | config.Scope.Add("rc.scope");
44 | config.Scope.Add("ApiOne");
45 | config.Scope.Add("ApiTwo");
46 | config.Scope.Add("offline_access");
47 |
48 | });
49 |
50 | services.AddHttpClient();
51 |
52 | services.AddControllersWithViews();
53 | }
54 |
55 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
56 | {
57 | if (env.IsDevelopment())
58 | {
59 | app.UseDeveloperExceptionPage();
60 | }
61 |
62 | app.UseRouting();
63 |
64 | app.UseAuthentication();
65 |
66 | app.UseAuthorization();
67 |
68 | app.UseEndpoints(endpoints =>
69 | {
70 | endpoints.MapDefaultControllerRoute();
71 | });
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/MvcClient/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | Home Page
--------------------------------------------------------------------------------
/MvcClient/Views/Home/Secret.cshtml:
--------------------------------------------------------------------------------
1 | Secret Page
--------------------------------------------------------------------------------
/MvcClient/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/MvcClient/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # aspnetcore3 Authentication Tutorial
2 |
3 | This repo is for my Youtube tutorial that can be found here: https://www.youtube.com/playlist?list=PLOeFnOV9YBa7dnrjpOG6lMpcyd7Wn7E8V
4 |
--------------------------------------------------------------------------------
/Server/Constants.cs:
--------------------------------------------------------------------------------
1 | namespace Server
2 | {
3 | public static class Constants
4 | {
5 | public const string Issuer = Audiance;
6 | public const string Audiance = "https://localhost:44382/";
7 | public const string Secret = "not_too_short_secret_otherwise_it_might_error";
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Server/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IdentityModel.Tokens.Jwt;
3 | using System.Security.Claims;
4 | using System.Text;
5 | using Microsoft.AspNetCore.Authorization;
6 | using Microsoft.AspNetCore.Mvc;
7 | using Microsoft.IdentityModel.Tokens;
8 |
9 | namespace Server.Controllers
10 | {
11 | public class HomeController : Controller
12 | {
13 | public IActionResult Index()
14 | {
15 | return View();
16 | }
17 |
18 | [Authorize]
19 | public IActionResult Secret()
20 | {
21 | return View();
22 | }
23 |
24 | public IActionResult Authenticate()
25 | {
26 | var claims = new[]
27 | {
28 | new Claim(JwtRegisteredClaimNames.Sub, "some_id"),
29 | new Claim("granny", "cookie")
30 | };
31 |
32 | var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
33 | var key = new SymmetricSecurityKey(secretBytes);
34 | var algorithm = SecurityAlgorithms.HmacSha256;
35 |
36 | var signingCredentials = new SigningCredentials(key, algorithm);
37 |
38 | var token = new JwtSecurityToken(
39 | Constants.Issuer,
40 | Constants.Audiance,
41 | claims,
42 | DateTime.Now,
43 | DateTime.Now.AddHours(1),
44 | signingCredentials);
45 |
46 | var tokenJson = new JwtSecurityTokenHandler().WriteToken(token);
47 |
48 | return Ok(new { access_token = tokenJson });
49 | }
50 |
51 | public IActionResult Decode(string part)
52 | {
53 | var bytes = Convert.FromBase64String(part);
54 | return Ok(Encoding.UTF8.GetString(bytes));
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/Server/Controllers/OAuthController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IdentityModel.Tokens.Jwt;
3 | using System.Security.Claims;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Authorization;
7 | using Microsoft.AspNetCore.Http.Extensions;
8 | using Microsoft.AspNetCore.Mvc;
9 | using Microsoft.IdentityModel.Tokens;
10 | using Newtonsoft.Json;
11 |
12 | namespace Server.Controllers
13 | {
14 | public class OAuthController : Controller
15 | {
16 | [HttpGet]
17 | public IActionResult Authorize(
18 | string responseType, // authorization flow type
19 | string clientId, // client id
20 | string redirectUri,
21 | string scope, // what info I want = email,grandma,tel
22 | string state) // random string generated to confirm that we are going to back to the same client
23 | {
24 | // ?a=foo&b=bar
25 | var query = new QueryBuilder();
26 | query.Add("redirectUri", redirectUri);
27 | query.Add("state", state);
28 |
29 | return View(model: query.ToString());
30 | }
31 |
32 | [HttpPost]
33 | public IActionResult Authorize(
34 | string username,
35 | string redirectUri,
36 | string state)
37 | {
38 | const string code = "BABAABABABA";
39 | var query = new QueryBuilder();
40 | query.Add("code", code);
41 | query.Add("state", state);
42 | return Redirect($"{redirectUri}{query}");
43 | }
44 |
45 | public async Task Token(
46 | string grantType, // flow of access_token request
47 | string code, // confirmation of the authentication process
48 | string redirectUri,
49 | string clientId,
50 | string refreshToken)
51 | {
52 | // some mechanism for validating the code
53 |
54 | var claims = new[]
55 | {
56 | new Claim(JwtRegisteredClaimNames.Sub, "some_id"),
57 | new Claim("granny", "cookie")
58 | };
59 |
60 | var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
61 | var key = new SymmetricSecurityKey(secretBytes);
62 | const string algorithm = SecurityAlgorithms.HmacSha256;
63 |
64 | var signingCredentials = new SigningCredentials(key, algorithm);
65 |
66 | var token = new JwtSecurityToken(
67 | Constants.Issuer,
68 | Constants.Audiance,
69 | claims,
70 | DateTime.Now,
71 | grantType == "refresh_token"
72 | ? DateTime.Now.AddMinutes(5)
73 | : DateTime.Now.AddMilliseconds(1),
74 | signingCredentials);
75 |
76 | var accessToken = new JwtSecurityTokenHandler().WriteToken(token);
77 |
78 | var responseObject = new
79 | {
80 | access_token = accessToken,
81 | token_type = "Bearer",
82 | raw_claim = "oauthTutorial",
83 | refresh_token = "RefreshTokenSampleValueSomething77"
84 | };
85 |
86 | var responseJson = JsonConvert.SerializeObject(responseObject);
87 | var responseBytes = Encoding.UTF8.GetBytes(responseJson);
88 |
89 | await Response.Body.WriteAsync(responseBytes, 0, responseBytes.Length);
90 |
91 | return Redirect(redirectUri);
92 | }
93 |
94 | [Authorize]
95 | public IActionResult Validate()
96 | {
97 | if (HttpContext.Request.Query.TryGetValue("access_token", out var accessToken))
98 | {
99 | return Ok();
100 | }
101 |
102 | return BadRequest();
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/Server/Controllers/SecretController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authorization;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace Server.Controllers
5 | {
6 | public class SecretController : Controller
7 | {
8 | [Authorize]
9 | public string Index()
10 | {
11 | return "secret message";
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Server/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 Server
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 |
--------------------------------------------------------------------------------
/Server/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:55580",
7 | "sslPort": 44382
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "Server": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Server/Server.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Server/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Authentication.JwtBearer;
2 | using Microsoft.AspNetCore.Builder;
3 | using Microsoft.AspNetCore.Hosting;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using Microsoft.Extensions.Hosting;
6 | using Microsoft.IdentityModel.Tokens;
7 | using System;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 |
11 | namespace Server
12 | {
13 | public class Startup
14 | {
15 | public void ConfigureServices(IServiceCollection services)
16 | {
17 | services.AddAuthentication("OAuth")
18 | .AddJwtBearer("OAuth", config =>
19 | {
20 | var secretBytes = Encoding.UTF8.GetBytes(Constants.Secret);
21 | var key = new SymmetricSecurityKey(secretBytes);
22 |
23 | config.Events = new JwtBearerEvents()
24 | {
25 | OnMessageReceived = context =>
26 | {
27 | if (context.Request.Query.ContainsKey("access_token"))
28 | {
29 | context.Token = context.Request.Query["access_token"];
30 | }
31 |
32 | return Task.CompletedTask;
33 | }
34 | };
35 |
36 | config.TokenValidationParameters = new TokenValidationParameters()
37 | {
38 | ClockSkew = TimeSpan.Zero,
39 | ValidIssuer = Constants.Issuer,
40 | ValidAudience = Constants.Audiance,
41 | IssuerSigningKey = key,
42 | };
43 | });
44 |
45 | services.AddControllersWithViews()
46 | .AddRazorRuntimeCompilation();
47 | }
48 |
49 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
50 | {
51 | if (env.IsDevelopment())
52 | {
53 | app.UseDeveloperExceptionPage();
54 | }
55 |
56 | app.UseRouting();
57 |
58 | app.UseAuthentication();
59 |
60 | app.UseAuthorization();
61 |
62 | app.UseEndpoints(endpoints =>
63 | {
64 | endpoints.MapDefaultControllerRoute();
65 | });
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Server/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 | Server Home Page
2 |
--------------------------------------------------------------------------------
/Server/Views/Home/Secret.cshtml:
--------------------------------------------------------------------------------
1 | Server Secret Page
--------------------------------------------------------------------------------
/Server/Views/OAuth/Authorize.cshtml:
--------------------------------------------------------------------------------
1 | @model string
2 |
3 | @{
4 | var url = $"/OAuth/Authorize{Model}";
5 | }
6 |
7 |
8 | @Model
9 |
10 |
--------------------------------------------------------------------------------
/Server/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Server/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft": "Warning",
6 | "Microsoft.Hosting.Lifetime": "Information"
7 | }
8 | },
9 | "AllowedHosts": "*"
10 | }
11 |
--------------------------------------------------------------------------------
/WpfApp/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WpfApp/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/WpfApp/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace WpfApp
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/WpfApp/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WpfApp/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel.OidcClient;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Net.Http;
6 | using System.Net.Http.Headers;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows;
10 | using System.Windows.Controls;
11 | using System.Windows.Data;
12 | using System.Windows.Documents;
13 | using System.Windows.Input;
14 | using System.Windows.Media;
15 | using System.Windows.Media.Imaging;
16 | using System.Windows.Navigation;
17 | using System.Windows.Shapes;
18 |
19 | namespace WpfApp
20 | {
21 | ///
22 | /// Interaction logic for MainWindow.xaml
23 | ///
24 | public partial class MainWindow : Window
25 | {
26 | private OidcClient _oidcClient = null;
27 |
28 | public MainWindow()
29 | {
30 | InitializeComponent();
31 | }
32 |
33 | private async void Button_Click(object sender, RoutedEventArgs e)
34 | {
35 | var options = new OidcClientOptions()
36 | {
37 | Authority = "https://localhost:44305/",
38 | ClientId = "wpf",
39 | Scope = "openid ApiOne",
40 | RedirectUri = "http://localhost/sample-wpf-app",
41 | Browser = new WpfEmbeddedBrowser()
42 | };
43 |
44 | _oidcClient = new OidcClient(options);
45 |
46 | LoginResult result;
47 | try
48 | {
49 | result = await _oidcClient.LoginAsync();
50 | }
51 | catch (Exception ex)
52 | {
53 | //Message.Text = $"Unexpected Error: {ex.Message}";
54 | return;
55 | }
56 |
57 | if (result.IsError)
58 | {
59 | //Message.Text = result.Error == "UserCancel" ? "The sign-in window was closed before authorization was completed." : result.Error;
60 |
61 | }
62 | else
63 | {
64 | var name = result.User.Identity.Name;
65 |
66 | var client = new HttpClient();
67 | client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
68 | var apiResult = await client.GetStringAsync("https://localhost:44337/secret");
69 | //Message.Text = $"Hello {name}";
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/WpfApp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("WpfApp")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("WpfApp")]
15 | [assembly: AssemblyCopyright("Copyright © 2020")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/WpfApp/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace WpfApp.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WpfApp.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/WpfApp/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace WpfApp.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/WpfApp/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/WpfApp/WpfEmbeddedBrowser.cs:
--------------------------------------------------------------------------------
1 | using IdentityModel.OidcClient.Browser;
2 | using System;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 |
9 | namespace WpfApp
10 | {
11 | public class WpfEmbeddedBrowser : IBrowser
12 | {
13 | private BrowserOptions _options = null;
14 |
15 | public WpfEmbeddedBrowser()
16 | {
17 |
18 | }
19 |
20 | public async Task InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default)
21 | {
22 | _options = options;
23 |
24 | var window = new Window()
25 | {
26 | Width = 900,
27 | Height = 625,
28 | Title = "IdentityServer Demo Login"
29 | };
30 |
31 | // Note: Unfortunately, WebBrowser is very limited and does not give sufficient information for
32 | // robust error handling. The alternative is to use a system browser or third party embedded
33 | // library (which tend to balloon the size of your application and are complicated).
34 | var webBrowser = new WebBrowser();
35 |
36 | var signal = new SemaphoreSlim(0, 1);
37 |
38 | var result = new BrowserResult()
39 | {
40 | ResultType = BrowserResultType.UserCancel
41 | };
42 |
43 | webBrowser.Navigating += (s, e) =>
44 | {
45 | if (BrowserIsNavigatingToRedirectUri(e.Uri))
46 | {
47 | e.Cancel = true;
48 |
49 | result = new BrowserResult()
50 | {
51 | ResultType = BrowserResultType.Success,
52 | Response = e.Uri.AbsoluteUri
53 | };
54 |
55 | signal.Release();
56 |
57 | window.Close();
58 | }
59 | };
60 |
61 | window.Closing += (s, e) =>
62 | {
63 | signal.Release();
64 | };
65 |
66 | window.Content = webBrowser;
67 | window.Show();
68 | webBrowser.Source = new Uri(_options.StartUrl);
69 |
70 | await signal.WaitAsync();
71 |
72 | return result;
73 | }
74 |
75 | private bool BrowserIsNavigatingToRedirectUri(Uri uri)
76 | {
77 | return uri.AbsoluteUri.StartsWith(_options.EndUrl);
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/WpfApp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/flutter_app/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Exceptions to above rules.
37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
38 |
--------------------------------------------------------------------------------
/flutter_app/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/flutter_app/README.md:
--------------------------------------------------------------------------------
1 | # flutter_app
2 |
3 | A new Flutter project.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
13 |
14 | For help getting started with Flutter, view our
15 | [online documentation](https://flutter.dev/docs), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/flutter_app/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/flutter_app/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 28
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.flutter_app"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 | }
57 |
58 | flutter {
59 | source '../..'
60 | }
61 |
62 | dependencies {
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'androidx.test:runner:1.1.1'
66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
67 | }
68 |
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/kotlin/com/example/flutter_app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.flutter_app
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.android.FlutterActivity
5 | import io.flutter.embedding.engine.FlutterEngine
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
10 | GeneratedPluginRegistrant.registerWith(flutterEngine);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/flutter_app/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/flutter_app/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_app/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/flutter_app/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/flutter_app/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/flutter_app/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/flutter_app/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/flutter_app/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/flutter_app/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/flutter_app/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/Authentication/97cc5e0e01fd9c087cf9f09b6b15b2e207e8bfd9/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_app
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/flutter_app/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/flutter_app/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:openid_client/openid_client_io.dart';
3 | import 'package:url_launcher/url_launcher.dart';
4 | import 'package:http/http.dart' as http;
5 |
6 | void main() => runApp(MyApp());
7 |
8 | class MyApp extends StatelessWidget {
9 | @override
10 | Widget build(BuildContext context) {
11 | return MaterialApp(
12 | title: 'Flutter Demo',
13 | theme: ThemeData(
14 | primarySwatch: Colors.blue,
15 | ),
16 | home: MyHomePage(title: 'Flutter Demo Home Page'),
17 | );
18 | }
19 | }
20 |
21 | class MyHomePage extends StatefulWidget {
22 | MyHomePage({Key key, this.title}) : super(key: key);
23 | final String title;
24 |
25 | @override
26 | _MyHomePageState createState() => _MyHomePageState();
27 | }
28 |
29 | class _MyHomePageState extends State {
30 | int _counter = 0;
31 |
32 | void _incrementCounter() {
33 | setState(() {
34 | _counter++;
35 | });
36 | }
37 |
38 | TokenResponse tokenResponse;
39 |
40 | void _auth() async {
41 | // create the client
42 | var uri = new Uri(scheme: "http", host: "192.168.1.107", port: 5000);
43 | var issuer = await Issuer.discover(uri);
44 | var client = new Client(issuer, "flutter");
45 |
46 | // create a function to open a browser with an url
47 | urlLauncher(String url) async {
48 | if (await canLaunch(url)) {
49 | await launch(url, forceWebView: true);
50 | } else {
51 | throw 'Could not launch $url';
52 | }
53 | }
54 |
55 | // create an authenticator
56 | var authenticator = new Authenticator(client,
57 | scopes: ["openid", "ApiOne"], port: 4000, urlLancher: urlLauncher);
58 |
59 | // starts the authentication
60 | var c = await authenticator.authorize();
61 | tokenResponse = await c.getTokenResponse();
62 |
63 | // close the webview when finished
64 | closeWebView();
65 | }
66 |
67 | void _callApi() async {
68 | var url = 'http://192.168.1.107:5002/secret';
69 | var access_token = tokenResponse.accessToken;
70 |
71 | var response = await http
72 | .get(url, headers: {"Authorization": "Bearer $access_token"});
73 | var body = response.body;
74 | var a = "";
75 | }
76 |
77 | @override
78 | Widget build(BuildContext context) {
79 | return Scaffold(
80 | appBar: AppBar(
81 | title: Text(widget.title),
82 | ),
83 | body: Center(
84 | child: Column(
85 | mainAxisAlignment: MainAxisAlignment.center,
86 | children: [
87 | OutlineButton(
88 | onPressed: _auth,
89 | child: Text("Login"),
90 | ),
91 | OutlineButton(
92 | onPressed: _callApi,
93 | child: Text("Call Api"),
94 | )
95 | ],
96 | ),
97 | ),
98 | floatingActionButton: FloatingActionButton(
99 | onPressed: _incrementCounter,
100 | tooltip: 'Increment',
101 | child: Icon(Icons.add),
102 | ),
103 | );
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/flutter_app/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_app
2 | description: A new Flutter project.
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # In Android, build-name is used as versionName while build-number used as versionCode.
10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
12 | # Read more about iOS versioning at
13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
14 | version: 1.0.0+1
15 |
16 | environment:
17 | sdk: ">=2.1.0 <3.0.0"
18 |
19 | dependencies:
20 | flutter:
21 | sdk: flutter
22 | cupertino_icons: ^0.1.2
23 | openid_client: ^0.2.5
24 | url_launcher: ^5.4.5
25 | http: ^0.12.1
26 |
27 | dev_dependencies:
28 | flutter_test:
29 | sdk: flutter
30 |
31 |
32 | # For information on the generic Dart part of this file, see the
33 | # following page: https://dart.dev/tools/pub/pubspec
34 |
35 | # The following section is specific to Flutter.
36 | flutter:
37 |
38 | # The following line ensures that the Material Icons font is
39 | # included with your application, so that you can use the icons in
40 | # the material Icons class.
41 | uses-material-design: true
42 |
43 | # To add assets to your application, add an assets section, like this:
44 | # assets:
45 | # - images/a_dot_burr.jpeg
46 | # - images/a_dot_ham.jpeg
47 |
48 | # An image asset can refer to one or more resolution-specific "variants", see
49 | # https://flutter.dev/assets-and-images/#resolution-aware.
50 |
51 | # For details regarding adding assets from package dependencies, see
52 | # https://flutter.dev/assets-and-images/#from-packages
53 |
54 | # To add custom fonts to your application, add a fonts section here,
55 | # in this "flutter" section. Each entry in this list should have a
56 | # "family" key with the font family name, and a "fonts" key with a
57 | # list giving the asset and other descriptors for the font. For
58 | # example:
59 | # fonts:
60 | # - family: Schyler
61 | # fonts:
62 | # - asset: fonts/Schyler-Regular.ttf
63 | # - asset: fonts/Schyler-Italic.ttf
64 | # style: italic
65 | # - family: Trajan Pro
66 | # fonts:
67 | # - asset: fonts/TrajanPro.ttf
68 | # - asset: fonts/TrajanPro_Bold.ttf
69 | # weight: 700
70 | #
71 | # For details regarding fonts from package dependencies,
72 | # see https://flutter.dev/custom-fonts/#from-packages
73 |
--------------------------------------------------------------------------------
/flutter_app/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_app/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------