日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Asp.Net Core Authentication Middleware And Generate Token

發(fā)布時間:2023/12/4 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Asp.Net Core Authentication Middleware And Generate Token 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

或者應(yīng)該包含什么信息呢?

    1.這個人是誰?

    2.這個人可以用此token訪問什么樣的內(nèi)容?(scope)

    3.token的過期時間 (expire)

    4.誰發(fā)行的token。

    5.其他任何你希望加入的聲明(Claims)

 那我們?yōu)槭裁匆褂胻oken呢?使用session或者用redis來實現(xiàn)stateServer不好嗎?

    1.token是低(無)狀態(tài)的,Statelessness

    2.token可以與移動端應(yīng)用緊密結(jié)合

    3.支持多平臺服務(wù)器和分布式微服務(wù)

拿到token后如何帶入HTTP請求傳給后臺?

? 答案是兩種方式,Cookies和Authorization Header。那么什么時候放到Cookies中,什么時候又放到Authentication中呢?

第一,如果是在Web應(yīng)用,則放到Cookies當(dāng)中,并且應(yīng)該是HttpOnly的,js不能直接對其進(jìn)行操作,安全性會比將其存在Web Stroage中好一些,因為在Web Storage當(dāng)中的內(nèi)容,可以很容的被潛在的XSS腳本攻擊并獲取。在HttpOnly的cookies當(dāng)中會相對安全一些,不過也有潛在的CSRF跨站偽造請求的危險,不過這種hack的手段成功率是很低的,有興趣的朋友可以自行看一下CSRF原理。

第二,如果是手機(jī)移動端應(yīng)用的話,那一定是存儲在App本地,并由Authorization Header帶到后臺并得到身份認(rèn)證。

WebApp Cookies Authentication

上一段前兩周寫的最原始的小Demo吧,沒有數(shù)據(jù)庫訪問等,可根據(jù)demo自行改變 ,現(xiàn)在的新代碼已經(jīng)加入了很多業(yè)務(wù)在其中

startup.cs代碼

using Microsoft.AspNetCore.Authentication.Cookies;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.AspNetCore.Http;

using Microsoft.AspNetCore.Http.Authentication;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using System.Collections.Generic;

using System.Security.Claims;

using Wings.AuthenticationApp.Middleware;


namespace Wings.AuthenticationApp

{

? ? public class Startup

? ? {

? ? ? ? public Startup(IHostingEnvironment env)

? ? ? ? {

? ? ? ? ? ? var builder = new ConfigurationBuilder()

? ? ? ? ? ? ? ? .SetBasePath(env.ContentRootPath)

? ? ? ? ? ? ? ? .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)

? ? ? ? ? ? ? ? .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)

? ? ? ? ? ? ? ? .AddEnvironmentVariables();

? ? ? ? ? ? Configuration = builder.Build();


? ? ? ? }


? ? ? ? public IConfigurationRoot Configuration { get; }


? ? ? ? // This method gets called by the runtime. Use this method to add services to the container.

? ? ? ? public void ConfigureServices(IServiceCollection services)

? ? ? ? {

? ? ? ? ? ? // Add framework services.

? ? ? ? ? ? services.AddMvc();

? ? ? ? }


? ? ? ? // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

? ? ? ? public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

? ? ? ? {

? ? ? ? ? ? loggerFactory.AddConsole(Configuration.GetSection("Logging"));

? ? ? ? ? ? loggerFactory.AddDebug();


? ? ? ? ? ? app.UseCookieAuthentication(CookieAuthMiddleware.GetOptions());

? ? ? ? ? ? app.UseOwin();

? ? ? ? ? ? app.UseCors(a => { a.AllowAnyOrigin(); });

? ? ? ? ? ? app.UseMvc();

? ? ? ? ? ? // Listen for login and logout requests

? ? ? ? ? ? app.Map("/login", builder =>

? ? ? ? ? ? {

? ? ? ? ? ? ? ? builder.Run(async context =>

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? var name = context.Request.Form["name"];

? ? ? ? ? ? ? ? ? ? var pwd = context.Request.Form["pwd"];

? ? ? ? ? ? ? ? ? ? if (name == "wushuang" && pwd == "wushuang")

? ? ? ? ? ? ? ? ? ? {


? ? ? ? ? ? ? ? ? ? ? ? var claims = new List<Claim>() { new Claim("name", name), new Claim("role", "admin") };

? ? ? ? ? ? ? ? ? ? ? ? var identity = new ClaimsIdentity(claims, "password");

? ? ? ? ? ? ? ? ? ? ? ? var principal = new ClaimsPrincipal(identity);

? ? ? ? ? ? ? ? ? ? ? ? await context.Authentication.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

? ? ? ? ? ? ? ? ? ? ? ? context.Response.Redirect("http://www.baidu.com");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

? ? ? ? ? ? ? ? ? ? ? ? context.Response.Redirect("http://www.google.com");

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? });

? ? ? ? ? ? });


? ? ? ? ? ? //app.Map("/logout", builder =>

? ? ? ? ? ? //{

? ? ? ? ? ? // ? ?builder.Run(async context =>

? ? ? ? ? ? // ? ?{

? ? ? ? ? ? // ? ? ? ?// Sign the user out / clear the auth cookie

? ? ? ? ? ? // ? ? ? ?await context.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);


? ? ? ? ? ? // ? ? ? ?// Perform a simple redirect after logout

? ? ? ? ? ? // ? ? ? ?context.Response.Redirect("/");

? ? ? ? ? ? // ? ?});

? ? ? ? ? ? //});

? ? ? ? ? ??

? ? ? ? }


? ? }

}

下面是Middleware---->CookieAuthMiddleware.cs的代碼,

using Microsoft.AspNetCore.Authentication.Cookies;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Http;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Security.Claims;

using System.Security.Principal;

using System.Threading.Tasks;


namespace Wings.AuthenticationApp.Middleware

{

? ? public class CookieAuthMiddleware

? ? {

? ? ? ? public static CookieAuthenticationOptions GetOptions()

? ? ? ? {

? ? ? ? ? ? return new CookieAuthenticationOptions

? ? ? ? ? ? {

? ? ? ? ? ? ? ? AutomaticAuthenticate = true,

? ? ? ? ? ? ? ? AutomaticChallenge = true,

? ? ? ? ? ? ? ? LoginPath = new PathString("/login"),

? ? ? ? ? ? ? ? LogoutPath = new PathString("/logout"),

? ? ? ? ? ? ? ? AccessDeniedPath = new PathString("/test"),

? ? ? ? ? ? ? ? CookieHttpOnly = false, ?//默認(rèn)就是True了

? ? ? ? ? ? ? ? CookieName = "wings_access_token",

? ? ? ? ? ? ? ? SlidingExpiration = true,

? ? ? ? ? ? ? ? CookieManager = new ChunkingCookieManager()

? ? ? ? ? ? };

? ? ? ? }

? ? }

? ? public static class IdentityExtension

? ? {

? ? ? ? public static string FullName(this IIdentity identity)

? ? ? ? {

? ? ? ? ? ? var claim = ((ClaimsIdentity)identity).FindFirst("name");

? ? ? ? ? ? return (claim != null) ? claim.Value : string.Empty;

? ? ? ? }

? ? ? ? public static string Role(this IIdentity identity)

? ? ? ? {

? ? ? ? ? ? var claim = ((ClaimsIdentity)identity).FindFirst("role");

? ? ? ? ? ? return (claim != null) ? claim.Value : string.Empty;

? ? ? ? }

? ? }

}

對應(yīng)如上demo,簡單測試一下,結(jié)果如下:

首先使用錯誤的密碼,來請求token endpoint,接下來我們看一下即使窗口,當(dāng)有請求進(jìn)入的時候,我用如下代碼判斷用戶的認(rèn)證情況,拿到的結(jié)果必然是false:

接下來,我使用正確的賬號密碼,來打入token,判斷結(jié)果一定為true,所以我使用自定義的拓展方法,來獲取下,該用戶token的信息:

如上demo沒有加入一些容錯機(jī)制,請注意。在用戶認(rèn)證成功后,可以進(jìn)入帶有Authorize Attribute的Action,否則401.如下是幾個重要參數(shù)的解釋

?

自定義Authentication Middle生產(chǎn)Token

?Startup.cs?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

using Wings.TokenAuth.Middleware;

using System.Security.Claims;

using Microsoft.IdentityModel.Tokens;

using System.Text;

using Microsoft.Extensions.Options;


namespace Wings.TokenAuth

{

? ? public class Startup

? ? {

? ? ? ? public Startup(IHostingEnvironment env)

? ? ? ? {

? ? ? ? ? ? var builder = new ConfigurationBuilder()

? ? ? ? ? ? ? ? .SetBasePath(env.ContentRootPath)

? ? ? ? ? ? ? ? .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)

? ? ? ? ? ? ? ? .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)

? ? ? ? ? ? ? ? .AddEnvironmentVariables();

? ? ? ? ? ? Configuration = builder.Build();

? ? ? ? }


? ? ? ? public IConfigurationRoot Configuration { get; }


? ? ? ? // This method gets called by the runtime. Use this method to add services to the container.

? ? ? ? public void ConfigureServices(IServiceCollection services)

? ? ? ? {

? ? ? ? ? ? // Add framework services.

? ? ? ? ? ? services.AddMvc();

? ? ? ? }


? ? ? ? // The secret key every token will be signed with.

? ? ? ? // In production, you should store this securely in environment variables

? ? ? ? // or a key management tool. Don't hardcode this into your application!

? ? ? ? private static readonly string secretKey = "mysupersecret_secretkey!123";


? ? ? ? public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

? ? ? ? {

? ? ? ? ? ? loggerFactory.AddConsole(LogLevel.Debug);

? ? ? ? ? ? loggerFactory.AddDebug();


? ? ? ? ? ? app.UseStaticFiles();


? ? ? ? ? ? // Add JWT generation endpoint:

? ? ? ? ? ? var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

? ? ? ? ? ? var options = new TokenProviderOptions

? ? ? ? ? ? {

? ? ? ? ? ? ? ? Audience = "ExampleAudience",

? ? ? ? ? ? ? ? Issuer = "ExampleIssuer",

? ? ? ? ? ? ? ? SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256),

? ? ? ? ? ? };


? ? ? ? ? ? app.UseMiddleware<TokenProviderMiddleware>(Options.Create(options));


? ? ? ? ? ? app.UseMvc();

? ? ? ? }

? ? }

}

TokenProviderOptions.cs

using Microsoft.AspNetCore.Http;

using Microsoft.Extensions.Options;

using Microsoft.IdentityModel.Tokens;

using Newtonsoft.Json;

using System;

using System.Collections.Generic;

using System.IdentityModel.Tokens.Jwt;

using System.Linq;

using System.Security.Claims;

using System.Threading.Tasks;


namespace Wings.TokenAuth.Middleware

{

? ? public class TokenProviderOptions

? ? {

? ? ? ? public string Path { get; set; } = "/token";


? ? ? ? public string Issuer { get; set; }


? ? ? ? public string Audience { get; set; }


? ? ? ? public TimeSpan Expiration { get; set; } = TimeSpan.FromMinutes(5);


? ? ? ? public SigningCredentials SigningCredentials { get; set; }

? ? }

? ? public class TokenProviderMiddleware

? ? {

? ? ? ? private readonly RequestDelegate _next;

? ? ? ? private readonly TokenProviderOptions _options;


? ? ? ? public TokenProviderMiddleware(

? ? ? ? ? RequestDelegate next,

? ? ? ? ? IOptions<TokenProviderOptions> options)

? ? ? ? {

? ? ? ? ? ? _next = next;

? ? ? ? ? ? _options = options.Value;

? ? ? ? }


? ? ? ? public Task Invoke(HttpContext context)

? ? ? ? {

? ? ? ? ? ? // If the request path doesn't match, skip

? ? ? ? ? ? if (!context.Request.Path.Equals(_options.Path, StringComparison.Ordinal))

? ? ? ? ? ? {

             //use new JwtSecurityTokenHandler().ValidateToken() to valid token

? ? ? ? ? ? ? ? return _next(context);

? ? ? ? ? ? }


? ? ? ? ? ? // Request must be POST with Content-Type: application/x-www-form-urlencoded

? ? ? ? ? ? if (!context.Request.Method.Equals("POST")

? ? ? ? ? ? ? || !context.Request.HasFormContentType)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? context.Response.StatusCode = 400;

? ? ? ? ? ? ? ? return context.Response.WriteAsync("Bad request.");

? ? ? ? ? ? }


? ? ? ? ? ? return GenerateToken(context);

? ? ? ? }

? ? ? ? private async Task GenerateToken(HttpContext context)

? ? ? ? {

? ? ? ? ? ? var username = context.Request.Form["username"];

? ? ? ? ? ? var password = context.Request.Form["password"];


? ? ? ? ? ? var identity = await GetIdentity(username, password);

? ? ? ? ? ? if (identity == null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? context.Response.StatusCode = 400;

? ? ? ? ? ? ? ? await context.Response.WriteAsync("Invalid username or password.");

? ? ? ? ? ? ? ? return;

? ? ? ? ? ? }


? ? ? ? ? ? var now = DateTime.UtcNow;


? ? ? ? ? ? // Specifically add the jti (random nonce), iat (issued timestamp), and sub (subject/user) claims.

? ? ? ? ? ? // You can add other claims here, if you want:

? ? ? ? ? ? var claims = new Claim[]

? ? ? ? ? ? {

? ? new Claim(JwtRegisteredClaimNames.Sub, username),

? ? new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

? ? new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64)

? ? ? ? ? ? };


? ? ? ? ? ? // Create the JWT and write it to a string

? ? ? ? ? ? var jwt = new JwtSecurityToken(

? ? ? ? ? ? ? issuer: _options.Issuer,

? ? ? ? ? ? ? audience: _options.Audience,

? ? ? ? ? ? ? claims: claims,

? ? ? ? ? ? ? notBefore: now,

? ? ? ? ? ? ? expires: now.Add(_options.Expiration),

? ? ? ? ? ? ? signingCredentials: _options.SigningCredentials);

? ? ? ? ? ? var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);


? ? ? ? ? ? var response = new

? ? ? ? ? ? {

? ? ? ? ? ? ? ? access_token = encodedJwt,

? ? ? ? ? ? ? ? expires_in = (int)_options.Expiration.TotalSeconds

? ? ? ? ? ? };


? ? ? ? ? ? // Serialize and return the response

? ? ? ? ? ? context.Response.ContentType = "application/json";

? ? ? ? ? ? await context.Response.WriteAsync(JsonConvert.SerializeObject(response, new JsonSerializerSettings { Formatting = Formatting.Indented }));

? ? ? ? }


? ? ? ? private Task<ClaimsIdentity> GetIdentity(string username, string password)

? ? ? ? {

? ? ? ? ? ? // DON'T do this in production, obviously!

? ? ? ? ? ? if (username == "wushuang" && password == "wushuang")

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return Task.FromResult(new ClaimsIdentity(new System.Security.Principal.GenericIdentity(username, "Token"), new Claim[] { }));

? ? ? ? ? ? }


? ? ? ? ? ? // Credentials are invalid, or account doesn't exist

? ? ? ? ? ? return Task.FromResult<ClaimsIdentity>(null);

? ? ? ? }


? ? ? ? public static long ToUnixEpochDate(DateTime date)

? => (long)Math.Round((date.ToUniversalTime() - new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero)).TotalSeconds);



? ? }

}

下面上測試結(jié)果:

使用錯誤的賬戶和密碼請求token

使用正確的賬戶和密碼來請求,返回結(jié)果如下:

如果,您認(rèn)為閱讀這篇博客讓您有些收獲,不妨點擊一下右下加【推薦】按鈕。
如果,您希望更容易地發(fā)現(xiàn)我的新博客,不妨點擊下方紅色【關(guān)注】的。
因為,我的分享熱情也離不開您的肯定支持。

感謝您的閱讀,我將持續(xù)輸出分享,我是蝸牛, 保持學(xué)習(xí),謹(jǐn)記謙虛。不端不裝,有趣有夢。

參考文章和論文,不僅限于如下幾篇,感謝國外大佬們有深度的分享:

http://stackoverflow.com/questions/29055477/oauth-authorization-service-in-asp-net-core

https://stormpath.com/blog/token-authentication-asp-net-core

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware#fundamentals-middleware

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/cookie#controlling-cookie-options

https://stormpath.com/blog/token-authentication-asp-net-core

相關(guān)文章:

  • AspNet Identity 和 Owin 誰是誰

  • ASP.NET Core 之 Identity 入門(一)

  • ASP.NET Core 之 Identity 入門(二)

  • ASP.NET Core 之 Identity 入門(三)

原文鏈接:http://www.cnblogs.com/tdws/p/6536864.html


.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注

總結(jié)

以上是生活随笔為你收集整理的Asp.Net Core Authentication Middleware And Generate Token的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。