net Framework OAuth2.0

grant_type

  1. client_credentials 客户端凭证
  2. password 密码模式 用于资源所有者密码凭据
  3. token 隐藏式 、 简化式 简化模式又称为隐式授权码模式,它是授权码模式的一个简化版本
  4. authorization_code 授权码
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    A. 第三方程序向资源拥有者(用户)发送授权请求,这个过程既可以通过客户端直接向用户请求,也可以通过授权服务器作为中介来完成请求。(注:对于授权请求这个概念相当于用户登录,应用程序可以直接显示一个登录页面,也可以跳转到验证服务器的统一登录页面)
      B. 用户将授权相关信息“提交”给第三方程序,在OAuth中有4种不同的权限授予方式,每种方式需要的数据不同,如基于用户密码的授权方式就需要用户名和密码。
      C. 第三方程序将用户的授权信息提交到授权服务器,请求一个Access Token。
      D. 授权服务器验证完成用户的授权信息后,将Access Token发放到第三方程序。
      E. 第三方程序携带Access Token访问被保护的资源。
      F. 资源服务器验证Access Token有效后,将资源返回到第三方程序。
       ● Authorization Code(授权码模式):该模式的核心是客户端通过一个授权码来向授权服务器申请Access Token。是一种基于重定向的授权模式,授权服务器作为用户和第三方应用(Client)的中介,当用户访问第三方应用是,第三方应用跳转到授权服务器引导用户完成身份验证,生成Authorization Code并转交到第三方应用,以便于第三方应用根据这个授权码完成后续的Access Token获取。
      ● Implicit(简化模式):简化模式是一种简化的授权码模式,授权码模式在首次访问第三方应用时跳转到授权服务器进行身份验证返回授权码,而简化模式在跳转到授权服务器后直接返回Access Token,这种模式减少了获取Access Token的请求次数。
      ● Resource Owner Password Credentials(用户密码模式):通过资源拥有者(用户)的用户名和密码来直接获取Access Token的一种方法,这种方法要求第三方应用(Client)是高度可信任的,并且其它授权方式不可用的情况下使用。
      ● Client Credentials(客户端模式):该模式是通过第三方应用(Client)发送一个自己的凭证到授权服务器获得Access Token,这种模式的使用要求该Client已经被授权服务器管理并限制其对被保护资源的访问范围。另外这种模式下Client应该就是一个资源拥有者(用户),如微服务程序。

》》》
四个模式中,只有【客户端模式】不需要用户输入用户名和密码,因为 客户端模式,不是用户名义请求的,是客户端本身名义请求的,所以需要后台提供 client_id 和 client_secret,
根据这个两个去认证服务器【Authorization server】 获取access_token.
》》适用于没有前端的命令行应用,即在命令行下请求令牌。一般用来提供给我们完全信任的服务器端服务。

如果是第一方应用(自己开发的应用)一般我们都认为要安全一些,因为不会故意的去泄露访问resource的access token, 所以一般第一方应用我们可以使用简单的【密码模式】, 这种节省了通过code去交换access token这一步骤(实际上就是节省了一次网络请求来回),直接通过用户名,密码去获取access token。而第三方应用我们需要采用更加安全的 【授权码模式】和【简单模式】

【授权码模式】和【简单模式】、【密码模式】 都需要用户录入用户名和密码, 但【授权码模式】和【简单模式】 是认证服务器【authorization server】提供的界面录入的,【密码模式】是客户端提供的界面录入的 ,所以认证服务器提供的界面更加安全些

【简单模式】是没有授权码【code】和刷新token【refresh_code】
>>>如果有人很容易的拿到code 或 refresh token,那么就基本上可以随意随时的去访问你的resource了,因为他可以不断的通过refresh token 去刷新access token。 而为什么第三方的SPA使用的是implicit flow 而第三方的Native App却使用的是authorization code flow? 理论上第三方应用都应该使用【授权码模式】,但是如果你仔细看下,【简化模式】中是没有code 和 refresh token的,而SPA应用(本质上是web,需要通过浏览器的)更加容易去暴露code 和 refresh token, 所以才在第三方的SPA应用中使用了【简单模式】,而只给了access token,

》》》

安装四个包

在这里插入图片描述

客户端模式 又称简化模式

客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向"服务提供商"进行 授权。

适用于没有前端的命令行应用,即在命令行下请求令牌。一般用来提供给我们完全信任的服务器端服务。

在这里插入图片描述
在这里插入图片描述

》》》》 用webapi 做案例 ,新建项目 【webapi】

在这里插入图片描述
在这里插入图片描述

》》》删除自动的Global.asax, 这个文件是程序的入口,删除之后要创建一个 OWIN Startup 命名为 Startup。
在这里插入图片描述

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using System.Web.Http;
using WebApplication3.App_Start;
using Microsoft.Owin.Cors;[assembly: OwinStartup(typeof(WebApplication3.Startup))]namespace WebApplication3
{public class Startup{public void Configuration(IAppBuilder app){           HttpConfiguration configuration = new HttpConfiguration();//注册Swagger//SwaggerConfig.Register(configuration);//注册WebAPIWebApiConfig.Register(configuration);//注册授权服务AuthorizationConfig.Register(app);//注册Json的数据展示格式JsonFormatConfig.Register(configuration);//跨域配置app.UseCors(CorsOptions.AllowAll);app.UseWebApi(configuration);}}
}

》》》 新建类 AuthorizationConfig
在这里插入图片描述


using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication3.Provider;namespace WebApplication3.App_Start
{public  class AuthorizationConfig{public static void Register(Owin.IAppBuilder app){OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,//允许http而非https访问TokenEndpointPath = new Microsoft.Owin.PathString(value: "/access_token"),//Token 请求地址AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),//Token的过期时间Provider = new OpenAuthorizationServerProvider(),//生成Token 配置RefreshTokenProvider = new OpenRefreshTokenProvider(),//生成RefreshToken的配置};app.UseOAuthAuthorizationServer(options);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}}
}

》》》新建类 JsonFormatConfig

在这里插入图片描述

using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;namespace WebApplication3.App_Start
{public class JsonFormatConfig{public static void Register(HttpConfiguration configuration){configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings(){ContractResolver = new CamelCasePropertyNamesContractResolver(),//小驼峰命名DateFormatString = "yyyy-MM-dd HH:mm:ss" //日期格式化};}}
}

》》》新建文件夹Provider
在这里插入图片描述
》》》新建类 OpenAuthorizationServerProvider 生成 access_token
在这里插入图片描述
在这里插入图片描述

using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Security.Claims;
using System.Security.Principal;namespace WebApplication3.Provider
{/// <summary>/// 授权服务器配置/// </summary>public class OpenAuthorizationServerProvider:OAuthAuthorizationServerProvider{/// <summary>/// 验证客户端信息/// </summary>/// <param name="context"></param>/// <returns></returns>public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){//如果是刷新token,且不要验证。if (context.Parameters.Get("refresh_token") == null){//获取clientId,ClientSecretstring clientId, clientSecret;if (!context.TryGetBasicCredentials(out clientId, out clientSecret)){context.TryGetFormCredentials(out clientId, out clientSecret);}//对客户端Id和客户端密码进行校验  是与数据库进行比对if (clientId == "zen" && clientSecret == "123456"){//通过客户端认证context.Validated(clientId);}else{context.Rejected();}}else{ // 通过客户端认证context.Validated();}return base.ValidateClientAuthentication(context);}/// <summary>/// 生成客户端模式Access_Token/// 还需要将对应的客户端信息存储在web中/// </summary>/// <param name="context"></param>/// <returns></returns>public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context){//以下即为认证成功//var identity = new ClaimsIdentity(context.Options.AuthenticationType);ClaimsIdentity identity = new GenericIdentity( name: context.ClientId, type: OAuthDefaults.AuthenticationType);//通过查数据库,得到一些用户的信息int userid = 13;string role = "管理员";string scope = "权限1,权限2";           identity.AddClaim(new Claim("userid", userid.ToString()));identity.AddClaim(new Claim("role", role));identity.AddClaim(new Claim("scope", scope));context.Validated(identity);return base.GrantClientCredentials(context);}}
}

》》》新建类 OpenRefreshTokenProvider 刷新token

在这里插入图片描述


using Microsoft.Owin.Security.Infrastructure;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Web;namespace WebApplication3.Provider
{/// <summary>/// 刷新Token配置/// </summary>public class OpenRefreshTokenProvider:AuthenticationTokenProvider{private static ConcurrentDictionary<string, string> _refreshTokens = new ConcurrentDictionary<string, string>();/// <summary>/// 生成Refresh_token/// </summary>/// <param name="context"></param>public override void Create(AuthenticationTokenCreateContext context){context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddDays(30);context.SetToken(tokenValue:Guid.NewGuid().ToString(format:"N")+Guid.NewGuid().ToString(format:"N"));_refreshTokens[context.Token] = context.SerializeTicket();//base.Create(context);   }/// <summary>/// 使用Refresh_token 请求Access_Token/// </summary>/// <param name="context"></param>public override void Receive(AuthenticationTokenReceiveContext context){string value;if (_refreshTokens.TryRemove(context.Token,out value)){context.DeserializeTicket(value);}base.Receive(context);}}
}

》》》 新建控制器
在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Web;
using System.Web.Http;namespace WebApplication3.Controllers
{public class HomeController : ApiController{// GET: Home[Authorize]public string Get(){var clientId = HttpContext.Current.User.Identity.Name;Dictionary<string,string> lst = new Dictionary<string,string>();foreach (Claim item in (this.User.Identity as ClaimsIdentity).Claims){lst.Add(item.Type,item.Value);}return "我是Get方法";}// GET: Homepublic string Get(int id){return $"这是参数为{id}的Get方法";}}
}

》》》测试 用postman
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

》》客户端凭证 走 GrantClientCredentials方法
在这里插入图片描述
在这里插入图片描述
ValidateAuthorizeRequest 》》》授权码验证
ValidateClientAuthentication 》》》客户端模式验证
ValidateClientRedirectUri
ValidateTokenRequest 》》》验证令牌请求, 简化模式、隐藏式模式

密码模式(Password Grant):

用户将用户名和密码发送给第三方应用程序,第三方应用程序直接向授权服务器请求访问令牌。

如果你高度信任某个应用,RFC 6749 也允许用户把用户名和密码,直接告诉该应用。该应用就使用你的密码,申请令牌,这种方式称为"密码式"(password)。

在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而授权服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

适用场景:公司搭建的授权服务器

在这里插入图片描述
(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

(C)认证服务器确认无误后,向客户端提供访问令牌。

在这里插入图片描述

在这里插入图片描述
其它都一样,修改OpenAuthorizationServerProvider 即可

using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Security.Claims;
using System.Security.Principal;namespace WebApplication3.Provider
{/// <summary>/// 授权服务器配置/// </summary>public class OpenAuthorizationServerProvider:OAuthAuthorizationServerProvider{public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){//获取用户传入的用户名和密码string UserName = context.UserName;string Password = context.Password;//通过查数据库,判断用户名和密码是否正确//以下只是一个示例,用户名必须以test开头if (!UserName.StartsWith("test")){context.SetError("invalid_grant", "用户名或密码不正确");return;}//以下即为认证成功//通过查数据库,得到一些用户的信息int userid = 13;string role = "管理员";string scope = "权限1,权限2";var identity = new ClaimsIdentity(context.Options.AuthenticationType);identity.AddClaim(new Claim("userid", userid.ToString()));identity.AddClaim(new Claim("role", role));identity.AddClaim(new Claim("scope", scope));context.Validated(identity);}/// <summary>/// 验证客户端信息/// </summary>/// <param name="context"></param>/// <returns></returns>public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){可以验证 ClientID、ClientSecret,或不验证//从上下文中获取ClientID和ClientSecretcontext.TryGetFormCredentials(out string clientId, out string clientSecret);//非法客户端if (clientId == null || !clientId.StartsWith("AAA")){context.SetError("invalid_clientId", "客户端没有授权");return Task.FromResult<object>(null);}//如果不验证可以直接执行下面的 验证通过context.Validated();           }        }
}

在这里插入图片描述

简化模式

有些 Web 应用是纯前端应用,没有后端。必须将令牌储存在前端。RFC 6749 就规定了第二种方式,允许直接向前端颁发令牌,这种方式没有授权码这个中间步骤,所以称为(授权码)“隐藏式”(implicit)

简化模式不通过第三方应用程序的服务器,直接在浏览器中向授权服务器申请令牌,跳过了"授权码"这个步骤,所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。所以 不会触发 ValidateClientAuthentication

这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication3.Provider;namespace WebApplication3.App_Start
{public  class AuthorizationConfig{public static void Register(Owin.IAppBuilder app){OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,//允许http而非https访问AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,//激活授权码模式TokenEndpointPath = new Microsoft.Owin.PathString(value: "/token"),//访问host/token获取AccessTokenAuthorizeEndpointPath = new Microsoft.Owin.PathString("/auth"),//访问host/auth获取授权码AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),//AccessToken在30分钟后过期Provider = new OpenAuthorizationServerProvider(),//AccessToken的提供类// 简化模式  省略下面代码   简化模式又称为隐式授权码模式,它是授权码模式的一个简化版本//AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(),//授权码的提供类 RefreshTokenProvider = new OpenRefreshTokenProvider(),//生成RefreshToken的配置};app.UseOAuthAuthorizationServer(options);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;namespace WebApplication3.Provider
{/// <summary>/// 授权服务器配置/// </summary>public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider{/// <summary>/// 验证重定向URI是否合法/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override async Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context){string url = context.RedirectUri;context.Validated(context.RedirectUri);}/// <summary>/// 验证请求信息是否合法/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override async Task ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context){if (context.AuthorizeRequest.ClientId.StartsWith("zen")){context.Validated();}else{context.Rejected();}}/// <summary>/// 完成认证,跳转到重定向URI/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context){var identity = new ClaimsIdentity("Bearer");context.OwinContext.Authentication.SignIn(identity);context.RequestCompleted();}  }
}

》》访问
在这里插入图片描述
》》直接跳转 access_token 是通过锚链接的
在这里插入图片描述
在这里插入图片描述

授权码模式 :

一、是获取授权码,
二、是获取AccessToken

在获取授权码时,我们需要请求host/auth这个地址,输入的参数有以下要求:

(1)grant_type,必须为authorization_code。

(2)response_type,必须为code。

(3)client_id,客户端ID。

(4)redirect_uri,重定向地址,如为http://abc.com/,
则请求授权码完成后,将会重定向到:http://abc.com/code=[授权码]。

(5)scope,授权范围,可选。

(6)state,客户端状态,可选。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

》》》Startup 同上
》》》JsonFormatConfig 同上
》》》api控制器同上
》》》OpenRefreshTokenProvider 刷新token 同上
》》》 AuthorizationConfig 类

在这里插入图片描述


using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebApplication3.Provider;namespace WebApplication3.App_Start
{public  class AuthorizationConfig{public static void Register(Owin.IAppBuilder app){OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,//允许http而非https访问AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,//激活授权码模式TokenEndpointPath = new Microsoft.Owin.PathString(value: "/token"),//访问host/token获取AccessTokenAuthorizeEndpointPath = new Microsoft.Owin.PathString("/auth"),//访问host/auth获取授权码AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),//AccessToken在30分钟后过期Provider = new OpenAuthorizationServerProvider(),//AccessToken的提供类// 简化模式  省略下面代码   简化模式又称为隐式授权码模式,它是授权码模式的一个简化版本AuthorizationCodeProvider = new OpenAuthorizationCodeProvider(),//授权码的提供类 RefreshTokenProvider = new OpenRefreshTokenProvider(),//生成RefreshToken的配置};app.UseOAuthAuthorizationServer(options);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}}
}

》》》OpenAuthorizationServerProvider

using Microsoft.Owin.Security.OAuth;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Infrastructure;namespace WebApplication3.Provider
{/// <summary>/// 授权服务器配置/// </summary>public class OpenAuthorizationServerProvider : OAuthAuthorizationServerProvider{/// <summary>/// 验证重定向URI是否合法/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override  Task ValidateClientRedirectUri(OAuthValidateClientRedirectUriContext context){string url = context.RedirectUri;context.Validated(context.RedirectUri);return base.ValidateClientRedirectUri(context);}/// <summary>/// 验证请求信息是否合法/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override async Task ValidateAuthorizeRequest(OAuthValidateAuthorizeRequestContext context){if (context.AuthorizeRequest.ClientId.StartsWith("zen")){context.Validated();}else{context.Rejected();}}/// <summary>/// 完成认证,跳转到重定向URI/// 授权码模式、简化模式 都会触发/// </summary>/// <param name="context"></param>/// <returns></returns>public override async Task AuthorizeEndpoint(OAuthAuthorizeEndpointContext context){//授权码模式var redirectUri = context.Request.Query["redirect_uri"];var clientId = context.Request.Query["client_id"];var identity = new ClaimsIdentity(new GenericIdentity(clientId, OAuthDefaults.AuthenticationType));        var authorizeCodeContext = new AuthenticationTokenCreateContext(context.OwinContext,context.Options.AuthorizationCodeFormat,new AuthenticationTicket(identity,new AuthenticationProperties(new Dictionary<string, string>{{"client_id", clientId},{"redirect_uri", redirectUri}}){IssuedUtc = DateTimeOffset.UtcNow,ExpiresUtc = DateTimeOffset.UtcNow.Add(context.Options.AccessTokenExpireTimeSpan)}));await context.Options.AuthorizationCodeProvider.CreateAsync(authorizeCodeContext);context.Response.Write(Uri.EscapeDataString(authorizeCodeContext.Token));//为了测试方便,直接打印出code//正常使用时是把code加在重定向网址后面//context.Response.Redirect(redirectUri + "?code=" + Uri.EscapeDataString(authorizeCodeContext.Token));context.RequestCompleted();}/// <summary>/// 验证客户端///// </summary>/// <param name="context"></param>/// <returns></returns>public override  Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){string cd = context.ClientId;string clientId, clientSecret;context.TryGetFormCredentials(out clientId, out clientSecret);if (!clientId.StartsWith("zen")){context.SetError("invalid_client", "未授权的客户端");return Task.FromResult<object>(null); ;}context.Validated();return Task.FromResult<object>(null);}/// <summary>/// 生成客户端模式Access_Token/// 还需要将对应的客户端信息存储在web中/// </summary>/// <param name="context"></param>/// <returns></returns>public override Task GrantClientCredentials(OAuthGrantClientCredentialsContext context){//以下即为认证成功return base.GrantClientCredentials(context);}public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){// 以下即为认证成功//var identity = new ClaimsIdentity(context.Options.AuthenticationType);ClaimsIdentity identity = new GenericIdentity(name: context.ClientId, type: OAuthDefaults.AuthenticationType);//通过查数据库,得到一些用户的信息int userid = 13;string role = "管理员";string scope = "权限1,权限2";identity.AddClaim(new Claim("userid", userid.ToString()));identity.AddClaim(new Claim("role", role));identity.AddClaim(new Claim("scope", scope));context.Validated(identity);return base.GrantResourceOwnerCredentials(context);}public override async Task ValidateTokenRequest(OAuthValidateTokenRequestContext context){if (context.TokenRequest.IsAuthorizationCodeGrantType){context.Validated();}else{context.Rejected();}}}
}

》》》 OpenAuthorizationCodeProvider

using Microsoft.Owin.Security.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;namespace WebApplication3.Provider
{public class OpenAuthorizationCodeProvider : IAuthenticationTokenProvider{private Dictionary<string, string> codes = new Dictionary<string, string>();public void Create(AuthenticationTokenCreateContext context){string new_code = Guid.NewGuid().ToString("n");context.SetToken(new_code);//context.SerializeTicket() 生成tokencodes.Add(new_code, context.SerializeTicket());}public Task CreateAsync(AuthenticationTokenCreateContext context){Create(context);return Task.FromResult<object>(null);}public void Receive(AuthenticationTokenReceiveContext context){string code = context.Token;if (codes.ContainsKey(code)){string value = codes[code];codes.Remove(code);context.DeserializeTicket(value);}}public Task ReceiveAsync(AuthenticationTokenReceiveContext context){Receive(context);return Task.FromResult<object>(null);}}
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

access_token

access_token不能暴露在浏览器那么该存放在哪?
重定向传回access_token会使安全保密性要求极高的访问令牌暴露在浏览器,增加访问令牌失窃风险。

在我看来,重定向携带的参数在URL上,http协议下重定向传回access_token的形式,是没有经过数据加密的,他会增加令牌失窃的风险。那么关于access_token存放在哪的问题,个人认为通过授权码以及客户端id和secret共同校验后获取的access_token,可以把access_token存放在localStorage中,localStorage虽然是永久存储,但是access_token会有一个有效期,有效期到了之后,即便access_token一直都存在但是有效期过后就无法访问到受保护资源。

》》》webstorage (sessionStorage和localStorage)
sessionStorage和localStorage区别
在这里插入图片描述
**注意: **不同浏览器无法共享localStorage或sessionStorage中的信息。
相同浏览器的不同页面间【相同域名和端口】可以共享相同的 localStorage,
但是不同页面或标签页间无法共享sessionStorage的信息。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/363442.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Cloud Networking] VLAN

1 为什么需要 VLAN(Virtual Local Area Network) VLAN是一个逻辑网络&#xff0c;VLAN将设备/用户进行逻辑分组&#xff0c;VLAN需要在Switch上创建。为什么需要这样呢&#xff1f;为何不能所有设备都在同一个网络&#xff1f; 如下网络&#xff0c;如果设备过多&#xff0c;…

计算机网络课程实训:局域网方案设计与实现(基于ensp)

文章目录 前言基本要求操作分公司1分公司2总部核心交换机配置实现内部服务器的搭建acl_deny部分用户与服务器出口出口防火墙配置 前言 本篇文章是小编实训部分内容&#xff0c;内容可能会有错误&#xff0c;另外ensp对电脑兼容性及其挑剔&#xff0c;在使用之前一定要安装好。…

找不到xinput1_3.dll怎么办,实测有效的几种方法分享

在日的使用电脑过程中&#xff0c;我们经常会遇到各种各样的问题。其中之一就是找不到xinput1_3.dll文件。这个问题可能会影响到我们的游戏体验&#xff0c;甚至导致电脑无法正常运行。那么&#xff0c;又该如何解决这个问题呢&#xff1f;小编将全面解析找不到xinput1_3.dll对…

K8S 角色/组件及部署方式的简单概述

1.宏观架构图 2.角色详情 2.1 Master(Controller Plane) 早期是叫 Master 节点&#xff0c;后期改名为 Controller Plane&#xff0c;负责整个集群的控制和管理 Master 不会干活的(当然你让它干也是会干的&#xff0c;涉及到污点容忍)&#xff0c;而是起到访问入口&#xff…

【python】一篇文零基础到入门:快来玩吧~

本笔记材料源于&#xff1a; PyCharm | 创建你的第一个项目_哔哩哔哩_bilibili Python 语法及入门 &#xff08;超全超详细&#xff09; 专为Python零基础 一篇博客让你完全掌握Python语法-CSDN博客 0为什么安装python和pycharm&#xff1f; 不同于c&#xff0c;c&#xff0…

深度学习训练基于Pod和RDMA

目录 ​编辑 引言 RDMA技术概述 InfiniBand iWARP RoCE Pod和容器化环境 深度学习训练与RDMA结合 MPI和RDMA 深度学习框架与RDMA 实战&#xff1a;基于Pod和RDMA的深度学习训练 环境准备 步骤 YAML 性能和优势 结论 引言 随着深度学习在人工智能领域的快速发展…

微服务框架中Nacos的个人学习心得

微服务框架需要学习的东西很多&#xff0c;基本上我把它分为了五个模块&#xff1a; 第一&#xff1a;微服务技术模块 分为三个常用小模块&#xff1a; 1.微服务治理&#xff1a; 注册发现 远程调用 配置管理 网关路由 2.微服务保护&#xff1a; 流量控制 系统保护 熔断降级 服…

OneForAll采坑记录

一、OneForAll 介绍 OneForAll是一款功能强大的子域收集工具。支持子域爆破、子域名验证、子域名置换、接管等功能。处理功能强大&#xff0c;速度极快&#xff0c;体验良好。 二、安装部署问题处理 github地址&#xff1a;https://github.com/shmilylty/OneForAll 环境要求…

探索未来的AI革命:GPT-5的即将登场

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

HarmonyOS ArkUi ArkWeb加载不出网页问题踩坑

使用 使用还是比较简单的&#xff0c;直接贴代码了 别忘了配置网络权限 Entry Component struct WebPage {State isAttachController: boolean falseState url: string State title: string Prop controller: web_webview.WebviewController new web_webview.WebviewCont…

企业级堡垒机JumpServer

文章目录 JumpServer是什么生产应用场景 Docker安装JumpServer1.Docker安装2.MySQL服务安装3.Redis服务安装4.key生成5.JumpServer安装6.登录验证 系统设置邮箱服务器用户和用户组创建系统审计员资产管理用户创建资产节点资产授权查看用户的资产监控仪表盘 命令过滤器创建命令过…

c++ 设计模式 的课本范例(上)

( 0 ) 这里补充面向对象设计的几个原则&#xff1a; 开闭原则 OCP &#xff1a; 面向增补开放&#xff0c;面向代码修改关闭。其实反映到代码设计上就是类的继承&#xff0c;通过继承与多态&#xff0c;可以不修改原代码&#xff0c;又增加新的类似的功能。 依赖倒置原则 Depen…

51单片机定时炸弹-准确计时-两根线随机一根触发中断可“拆弹“(AT89C52)

一、设计介绍: 1、使用定时器按照精确时间读秒倒计时&#xff0c;倒计时在LCD1602中居中显示&#xff0c;格式为mm&#xff1a;ss&#xff0c;每秒变化一次 2、默认倒计时10分钟&#xff0c;时间到后显示“Time over”“&#xff08;&#xff08;&#xff08;Boom&#xff09…

抗击.michevol勒索病毒:保障数据安全的新策略

导言&#xff1a; 在今天高度互联的数字化环境中&#xff0c;数据安全面临着越来越复杂和普遍的威胁&#xff0c;勒索病毒如.michevol已成为了用户和企业普遍面临的风险。本文91数据恢复将探讨.michevol勒索病毒的特点、感染方式以及创新的防御策略&#xff0c;旨在帮助读者更…

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens

【IJCAI2024】LeMeViT: Efficient Vision Transformer with Learnable Meta Tokens for Remote Sensing Image Interpretation 论文&#xff1a;https://arxiv.org/abs/2405.09789 代码&#xff1a;https://github.com/ViTAE-Transformer/LeMeViT 由于相邻像素和图像块之间的高…

Solana最新上线的Blink功能引爆加密圈:杀手级应用还是花拳绣腿?

近日&#xff0c;Solana推出了其最新功能——Blink&#xff0c;这一功能迅速引爆了加密圈的讨论。Blink功能能够将链上的操作&#xff0c;如交易、投票、支付、铸币等转化为一个可分享的链接或二维码&#xff0c;允许用户在不跳转其他页面的情况下直接在推特上完成上述链上操作…

【代码工厂】简单地图生成

要求 &#xff08;图片来自codingame&#xff09; 代码 # 定义一个函数&#xff0c;用于生成模式 def generate_pattern(n, a, border_char): # 初始化一个空列表&#xff0c;用于存储生成地图pattern []# 最上面那一行的处理line n * border_charpattern.append(line)# 遍…

建投数据人力资源管理系统APP完成迭代升级

近日&#xff0c;建投数据人力资源管理系统APP完成迭代升级。 此次升级思路&#xff0c;遵循提升移动应用的功能和用户体验&#xff1b;直观的界面、快速的响应速度和安全的数据存储&#xff1b;个性化的功能&#xff0c;以满足不同员工的需求和使用偏好。 人力资源管理系统A…

行业推荐!IG5216量产工具下载,IG5216开卡软件分享

国内固态硬盘常用&#xff0c;且有量产工具流传出来的主控厂商包括慧荣、群联、点序、英韧、得一微、瑞昱、联芸、迈威、国科、华澜微等等。 每个主控需要用各自对应的量产工具&#xff0c;不同的量产工具支持的闪存颗粒也有差异&#xff0c;因此要根据固态硬盘实际的主控型号…

SpringBoot集成道历(实现道历日期查询)

官网地址&#xff1a;官网地址https://6tail.cn/calendar/api.html 1、导入依赖 <dependency><groupId>cn.6tail</groupId><artifactId>lunar</artifactId><version>1.3.9</version></dependency><dependency><group…