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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

rsviwe32 7.6 授权_「复杂系统迁移 .NET Core平台系列」之认证和授权

發布時間:2024/10/8 windows 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rsviwe32 7.6 授权_「复杂系统迁移 .NET Core平台系列」之认证和授权 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

源寶導讀:微軟跨平臺技術框架—.NET Core已經日趨成熟,已經具備了支撐大型系統穩定運行的條件。本文將介紹明源云ERP平臺從.NET Framework向.NET Core遷移過程中的實踐經驗。

一、背景

隨著ERP的產品線越來越多,業務關聯也日益復雜,應用間依賴關系也變得錯綜復雜,單體架構的弱點日趨明顯。19年初,由于平臺底層支持了分應用部署模式,將ERP從應用子系統層面進行了切割分離,邁出了從單體架構向微服務架構轉型的堅實一步。不久的將來,ERP會進一步將各業務拆分成眾多的微服務,而微服務勢必需要進行容器化部署和運行管理,這就要求ERP技術底層必須支持跨平臺,所以將現有ERP系統從.NET Framework遷移到 .NET Core平臺勢在必行。

上一篇我們講述了Erp改造.Net Core之靜態文件,這一篇我們將講述在認證和授權改造過程中遇到的問題和解決思路。

二、關于認證和授權

權限控制是應用程序中最常見的需求,無論是在Asp.Net還是Asp.Net Core中都有相應的支持,而權限控制在框架層面支持主要是兩部分,身份認證和身份授權:

  • 身份認證:識別當前請求的用戶信息,一般是通過加密的Cookies實現。
  • 身份授權:識別當前請求是否有訪問指定資源的權限,一般是根據當前請求識別的用戶信息,結合角色權限相關配置來判斷。

三、Asp.Net認證和授權的實現

這里不區分Asp.Net WebForm和Asp.Net MVC,因為兩者都是基于HttpModule來進行身份認證和授權。

在Asp.Net中認證是通過FormsAuthenticationModule實現,授權是通過UrlAuthorizationModule實現,需要在web.config中做如下配置:

簡述一下用戶訪問網站授權一個流程:

  • 假設用戶訪問首頁/PubPlatform/Nav/Home/Default.aspx。
  • UrlAuthorizationModule 根據禁止匿名用戶訪問的配置,要求用戶進行身份認證。
  • 跳轉到登陸頁面/ PubPlatform/ Login/index.aspx進行身份認證。
  • 服務端判斷用戶輸入用戶密碼信息。
  • 如果驗證通過將認證信息寫入Repsonse的Cookies中并跳轉到/PubPlatform/Nav/Home/Default.aspx。
  • UrlAuthorizationModule 根據配置發現已經有用戶信息直接,開始進入到HttpHandler處理程序。
  • PS:整個認證過程遠比這個復雜,因為本文重點不在這里,只做簡單的描述,了解基本流程即可,有興趣可以參考https://www.cnblogs.com /fish-li/archive/2012/04/15/2450571.html。

    第二段配置中,通過用戶所在的組來控制是否有modeling目錄的訪問權限,如果需要更多的權限配置可以添加更多類似的配置,實際在使用過程中很少使用這種方式,因為用戶角色和頁面會有很多,配置會很多而且不能實現動態配置,所以一般是在應用程序中處理,在Webform中一般采用類似如下方式:

    public class BacePage:Page

    {

    protected override void OnLoad(EventArgs e)

    {

    //在這里根據HttpContext.User來獲取用戶信息然后獲取角色權限來判斷當前資源可否訪問

    base.OnLoad(e);

    }

    }

    在Mvc中一般采用繼承自AuthorizationFilterAttribute來處理,邏輯跟上述代碼中演示的類似。

    四、Asp.Net Core

    在Core中引入Authentication需要在Startup.cs進行引入,一般和老版本一樣使用Cookies做認證信息的承載,承載的代碼如下:

    public void ConfigureServices(IServiceCollection services)

    {

    ...

    services.AddAuthentication("Cookies")

    .AddCookie("Cookies");

    ...

    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    {

    ...

    app.UseAuthentication();

    ...

    }

    在ConfigureServices(應用初始化過程),引入了Cookies作為默認的認證方式,在Configure(管道初始化)過程中引入認證的中間件。下面會簡要分析下認證和授權的過程:

  • 請求進入Authentication Middleware中間件之后首先會IAuthentication RequestHandler 接口做權限判斷,這個組件主要使用來做遠程認證的,例如SSO登錄的場景。然后再做默認的認證:以Cookies認證為例,主要是讀取Cookies的信息到HttpContext.User中。
  • 經過中間件之后會進入AuthorizeFilter中(這里和認證和授權的核心地方)。
  • 獲取全局,Controller,Action之上的元數據計算之后得出AuthorizationPolicy。
  • 通過IPolicyEvaluator調用Authentication模塊進行認證信息解析。
  • 通過IPolicyEvaluator攜帶Authentication結果調用Authentization模塊進行授權信息解析。
  • 核心代碼如下:

    //AuthenticationMiddleware 部分代碼

    public async Task Invoke(HttpContext context)

    {

    context.Features.Set(new AuthenticationFeature

    {

    OriginalPath = context.Request.Path,

    OriginalPathBase = context.Request.PathBase

    });

    // Give any IAuthenticationRequestHandler schemes a chance to handle the request

    var handlers = context.RequestServices.GetRequiredService();

    foreach (var scheme in await Schemes.GetRequestHandlerSchemesAsync())

    {

    var handler = await handlers.GetHandlerAsync(context, scheme.Name) as IAuthenticationRequestHandler;

    if (handler != null && await handler.HandleRequestAsync())

    {

    return;

    }

    }

    var defaultAuthenticate = await Schemes.GetDefaultAuthenticateSchemeAsync();

    if (defaultAuthenticate != null)

    {

    var result = await context.AuthenticateAsync(defaultAuthenticate.Name);

    if (result?.Principal != null)

    {

    context.User = result.Principal;

    }

    }

    await _next(context);

    }

    // AuthorizeFilte部分代碼

    public virtual async Task OnAuthorizationAsync(AuthorizationFilterContext context)

    {

    if(context == null)

    {

    throw new ArgumentNullException(nameof(context));

    }

    if (!context.IsEffectivePolicy(this))

    {

    return;

    }

    // IMPORTANT: Changes to authorization logic should be mirrored in security's AuthorizationMiddleware

    var effectivePolicy = await GetEffectivePolicyAsync(context);

    if (effectivePolicy == null)

    {

    return;

    }

    var policyEvaluator = context.HttpContext.RequestServices.GetRequiredService();

    var authenticateResult = await policyEvaluator.AuthenticateAsync(effectivePolicy, context.HttpContext);

    // Allow Anonymous skips all authorization

    if (HasAllowAnonymous(context))

    {

    return;

    }

    var authorizeResult = await policyEvaluator.AuthorizeAsync(effectivePolicy, authenticateResult, context.HttpContext, context);

    if (authorizeResult.Challenged)

    {

    context.Result = new ChallengeResult(effectivePolicy.AuthenticationSchemes.ToArray());

    }

    else if (authorizeResult.Forbidden)

    {

    context.Result = new ForbidResult(effectivePolicy.AuthenticationSchemes.ToArray());

    }

    }

    如果有興趣的話可以繼續往里面跟蹤一下代碼發現最終起作用的是IAuthentication Handler和IAuthorizationHandler,而最終這兩個Handler的引入在Core中對應兩個概念:

    • AuthenticationScheme 認證計劃。
    • AuthorizationRequirement 授權條件。

    最終Core的認證和授權一般都是通過這兩個來進行擴展,這里特別說明一點,在Mvc Core中將身份認證和授權進行了統一的規劃。因為在認證過程中,MVC Core只是只是解析,但并不實際將Http請求進行返回處理。實際過程是在AuthorizationRequirement進行處理的,這里特別提到Mvc Core中的默認授權DenyAnonymousAuthorizationRequirement,通過這個授權條件判斷是否有認證的用戶信息來進行權限的判斷。

    資源能否訪問這個理解為授權,那么身份認證只是授權的一種方式。

    在Asp.Net WebFrom中使用基于HttpModule進行身份認證會丟失掉很多元數據的信息,因為最終方法的執行是在HttpHandler上,而HttpModule并不知道那個Handler也不知道是那個方法,就會大量使用HttpContext的解析,提高了復雜度。

    如果在HttpModule中進行,如果有多種身份認證方式,那么無論最終資源需要何種方式都會經過很多HttpModule,走了無謂的分支。

    另外Webfrom中授權一般寫在基類中,基類必定會引入不同的繼承分支,這樣也不便于維護.對比Mvc Core中使用的特性標記+策略者的使用方式,更加利于維護和擴展,而不用對原有邏輯進行變動。

    對比Asp.Net MVC中其中有IAuthenticationFilter和IAuthorizationFilter來處理授權和認證,然而在Asp.Net MVC Core中 只有IAuthorizationFilter。

    對于資源的訪問應該只有可否訪問的判斷即授權,而是否身份認證只能說是判斷授權一種常用方式,在MVC Core中將認證通過DenyAnonymousAuthorizationRequirement融入授權以后,真正的將授權和認證融為一體,而非之前看似兩個并行的概念,相互不同的處理邏輯。

    在Mvc Core通過AOP進行接入,然后一系列的封裝,最終將身份和授權通過Scheme + IAuthrenticationHandler和Requirement + AuthorizationHandler,這種類似于策略者模式的方式,對外提供擴展。更加易于擴展,而實際并不用太多考慮AOP部分的邏輯。最終授權和認證之需要我們進行Attribute標記然后MVC Core會自動加載到自己的元數據中,另外在RazorPage還可以主動調用如下方法進行授權的添加:

    //對目錄進行授權

    RazorPageOptions.Conventions.AuthorizeFolder();

    //對頁面進行授權

    RazorPageOptions.Convertions.AuthorizePage();

    五、ERP認證和授權

    ERP頁面的部分使用傳統webform的認證體系,而提供的接口部分使用了自定義HttpModule的方式,由于很多ERP演化升級過程中被動接受了很多身份認證方式的接入,所以原本實現授權的HttoModule的邏輯變得異常復雜,而這一次在改造Core的過程中進行了全面的改造后面會進行講述。同樣授權也是一樣,將原本實現在Page基類中的復雜的判斷邏輯進行了改造。

    ERP在pub接口的身份認證方面需要實現對如下不同的方式:

    • Pub接口
    • 內部集成
    • 接口管家
    • Mip集成
    • OA集成

    之前講過ERP是通過元數據來驅動的頁面邏輯,權限實際是通過通過元數據配置到界面元素上的權限點來進行標識。通過常用的用戶-角色-權限的模型模型來關聯用戶和權限點,然后通過在Page的基類中通過拿到用戶的權限來判斷是否有當前URL的訪問權限,在按鈕渲染的時候來獲取是否有該按鈕的權限點來控制是否顯示。

    在這次的改造過程中我們進行了如下改造:

  • Mvc Core CookiesAuthentication中間件來實現頁面的身份認證。
  • 擴展MVC Core 的 AuthenticationScheme來實現接口的身份認證。
  • 擴展MVC Core 的 Authentization Policy +Requirement來實現頁面的身份授權。
  • 下面通過這三部分進行講述。

    5.1、CookiesAuthentication身份認證

    MVC Core 自帶的基于Cookies的身份認證已經能滿足我們的需求,只需要稍微進行一下配置即可。通過一張圖我們了解下整個的身份認證流程,使用代碼參考本章開頭Asp.Net Core對認證和授權進行分析的部分。

    因為只是使用來說已經比較簡單這里不做過多的描述。這里有一個點需要注意,在Cookie的認證中如果是負載均衡的場景,兩個不同進程的引用需要都可以進行客戶端Cookies的解密。那么就需要共享加解密的key,這里我們使用MVC Core自帶的基于Entity Framework Core 的密鑰持久化方式,通過存放到數據庫來實現密鑰的共享。這部分內容可以參考:https://docs.microsoft.com/zh-cn/aspnet/core/security/data-protection/implementation/key-storage-providers?view=aspnetcore-3.1&tabs=visual-studio。

    5.2、Pub接口的身份認證

    除了頁面訪問以及頁面ajax請求這些事基于Cookies的身份認證之外,在提供的接口用了其他的認證方式,這次將所有接口的認證方式進行了抽象,統一使用OpenApi的Scheme進行認證,而實際各種不同的認證方式我們是通過實入AuthenticationMiddleware中調用的IAuthenticationRequestHandler來實現的。首先我們看一下執行的流程:

    之前有一篇關于Mvc Core的Controller改造的文章,其中將pub接口的發現和特性路由擴展進行了擴展,這里我們在擴展的地方添加OpenApi類型Scheme的元數據。

    因為我們的接口統一是使用/pub/開頭的所以我們選擇使用擴展IAuthentication RequestHandler來實現,這樣在判斷是否要進行認證的時候需要判斷url是否以pub開頭即可,下面是類圖:

    其中核心就是MockUserAuthHandler,因為在Erp的接口中都會用到用戶相關的信息,所以我們所有的pub接口操作實際的身份認證都是模擬了用戶的認證,這里將這個概念顯式的移動到基類之中,我們通過如下代碼進行接入: 這里我們添加了眾多的Scheme只是為了在AuthenticationMiddleware中處理請求并進行模擬用戶登錄,并未有實際的Action上有此Sheme,在Action上使用的只有AppConst.ApiSchemeName(“OpenApiScheme”)。

    在Cookies的認證的流程中因為是在登錄過程中將認證信息寫到Cookies中,而其他請求只需要進行Cookies解析即可獲得用戶信息。而pub接口請求是在一個用戶請求過程中完成整個過程,實際是通過解析Header的特定內容,然后跟保存在Erp中的認證信息進行對比來確定身份,最后在模擬用戶之后,進行登錄操作來完成整個身份認證的流程。

    這里我們采用擴展IAuthentication RequestHandler的方式有如下考慮:

  • 如果采用IAuthenticationHandler + Sheme,Core的標準是按照不同的請求使用不同Scheme無法支持,而實際來說都是通過pub接口進行區分,并沒有區分到具體的請求。
  • 目前ERP的認證方式跟行業標準方案不同,以后如果接入標準方案,增加Scheme更加容易擴展并兼容現有方案。
  • IAuthenticationRequestHandler官方給出是遠程認證時候使用,在以后前后端分離加上微服務的升級過程中,只需要修改這部分請求中認證信息發送給遠程服務器認證即可,更加符合官方推薦使用的風格。
  • 綜合來說采取IAuthentication RequestHandler而不采用IAuthenticationHandler + Sheme 方式,還是基于官方給出的推薦使用風格和Erp擴展需求綜合考慮而來。

    5.3、Razor頁面授權

    在頁面改造篇我們講述了頁面改造的過程,我們知道RazorPage實際是類似CodeBehind的模式,通過PageModel的OnGet方法,每個頁面都有對應的PageModel,所以我們這里定義的BasePageModel基類如下:

    public static AuthenticationBuilder AddOpenApiAuth(this AuthenticationBuilder builder)

    {

    builder.AddScheme(AppConst.ApiSchemeName, AppConst.ApiSchemeName,null);

    return builder.AddScheme(AppConst.OpenApi, AppConst.OpenApi, null)

    .AddScheme(AppConst.AccessToken, AppConst.AccessToken, null)

    .AddScheme(AppConst.OAuthV1, AppConst.OAuthV1, null)

    .AddScheme(AppConst.OAuthV2, AppConst.OAuthV2, null)

    .AddScheme(AppConst.InternalIntegration, AppConst.InternalIntegration, null);

    }

    這里我們使用Cookies的Scheme進行授權,特別的是我們還增加了AuthentizationPolicy的定義,通過定義的Policy加上PolicyProvider來實現不同的Policy的切換,Policy的使用代碼如下:

    public static IMvcBuilder AddFrontend(this IMvcBuilder builder)

    {

    builder.AddRazorPagesOptions(options =>

    {

    //…

    //建模的權限

    options.Conventions.AuthorizeFolder(“/modeling”, AppConst.ModelingAuth);

    });

    //頁面權限

    builder.Services.AddMapAuth();

    //...

    }

    //注冊

    private static void AddMapAuth(this IServiceCollection services)

    {

    services.AddSingleton();

    services.TryAddEnumerable(ServiceDescriptor.Transient());

    services.TryAddEnumerable(ServiceDescriptor.Transient());

    services.TryAddEnumerable(ServiceDescriptor.Transient());

    }

    //Policy實現

    internal class MapAuthPolicyProvider : IAuthorizationPolicyProvider

    {

    private DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }

    public MapAuthPolicyProvider(IOptions options)

    {

    FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);

    }

    public Task GetPolicyAsync(string policyName)

    {

    if (policyName.StartsWith(AppConst.ModelingAuth, StringComparison.OrdinalIgnoreCase))

    {

    var policy = new AuthorizationPolicyBuilder();

    policy.AddRequirements(new ModelingRequirement());

    return Task.FromResult(policy.Build());

    }

    if (policyName.StartsWith(AppConst.AppAuth, StringComparison.OrdinalIgnoreCase))

    {

    var policy = new AuthorizationPolicyBuilder();

    policy.AddRequirements(new AppAuthRequirement());

    return Task.FromResult(policy.Build());

    }

    if (policyName.StartsWith(AppConst.UserAuth, StringComparison.OrdinalIgnoreCase))

    {

    var policy = new AuthorizationPolicyBuilder();

    policy.AddRequirements(new UserAuthRequirement());

    return Task.FromResult(policy.Build());

    }

    //返回默認的認證

    return FallbackPolicyProvider.GetPolicyAsync(policyName);

    }

    public Task GetDefaultPolicyAsync()

    {

    return FallbackPolicyProvider.GetDefaultPolicyAsync();

    }

    }

    通過上述代碼實現了不同策略使用不同的Requirement進行授權的校驗,至于授權校驗邏輯就是常見的用戶權限判斷。下面是整體的執行流程:

    六、總結

    Core認證和授權改造主要是要對Core的認證和授權的邏輯要清晰,這里核心就是去扒源碼,由于之前對Asp.Net MVC的了解,直接就從AuthorizeFilter入手很快就可以找到切入點,然后了解到整個Core認證和授權的核心。

    權限這部分的改造不僅僅只是代碼的遷移,也是風格的一個改造,將原來認證和授權的大泥球的設計,通過Core提供的Scheme+Requirement的擴展進行結合的重新設計。

    ------ END ------

    作者簡介

    熊同學: 研發工程師,目前負責ERP運行平臺的設計與開發工作。

    公眾號:明源技術

    總結

    以上是生活随笔為你收集整理的rsviwe32 7.6 授权_「复杂系统迁移 .NET Core平台系列」之认证和授权的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 影音先锋成人资源网站 | 国产a级免费 | 国产最爽的乱淫视频国语对白 | 嫩草视频一区二区三区 | 男人私人影院 | 18国产免费视频 | 国产精品av在线免费观看 | 午夜精产品一区二区在线观看的 | 国产盗摄一区二区三区 | 日韩电影一区二区三区四区 | 五月天男人天堂 | 精品黑人一区二区三区久久 | 手机av在线免费观看 | 性高潮网站 | 精品亚洲乱码一区二区 | 午夜精品久久久久久久久久久久久 | 亚洲精品91在线 | 99热18 | 性生交生活影碟片 | a天堂在线资源 | 国产不卡av在线播放 | 91在线网址 | 成年人精品 | 天天插天天狠天天透 | 国产福利91精品一区二区三区 | 青青超碰| 欧美日韩亚洲一区二区 | 日韩在线资源 | 暖暖日本在线 | 新婚若妻侵犯中文字幕 | 黄色大毛片 | 一级黄色录像免费观看 | 老牛嫩草二区三区观影体验 | 九九九精品视频 | 国产网友自拍视频 | 国产网友自拍视频 | 97黄色网 | 性插插视频 | www.久久视频 | 青青青青在线 | 亚洲国产日韩一区二区 | 三级黄色av | 国产精品theporn | 国内精品免费 | 视频在线亚洲 | 久久狠狠干 | 亚洲片在线观看 | 精品成人av一区二区在线播放 | 欧美自偷自拍 | 最新福利在线 | √天堂资源地址在线官网 | 男人的天堂99 | 亚洲欧洲日韩 | 亚洲精品视频在线播放 | 潮喷失禁大喷水aⅴ无码 | 日本啪啪片| 国产一级二级三级视频 | jizzjizz欧美69巨大| 17c在线 | 俄罗斯嫩小性bbwbbw | 国产a线| 国产成人8x视频一区二区 | 免费成人深夜夜行网站视频 | 特级新鲜大片片 | 超碰蜜桃 | 波多野结衣1区2区3区 | 日韩中文字幕免费在线观看 | 一区二区精品在线观看 | 日本人的性生活视频 | 天天插av| 夜夜狠 | 光棍影院手机版在线观看免费 | 一本色综合 | 美女又爽又黄视频毛茸茸 | av大片免费在线观看 | 亚洲国产mv | 青娱乐青青草 | 久久人人爽人人爽人人片亚洲 | 中文字幕2区 | 一区二区三区激情视频 | 日本乱偷中文字幕 | 一级片麻豆| 岛国av在线 | 国产亚洲欧美在线精品 | 成人午夜影片 | 巨茎大战刘亦菲 | 影音先锋91 | 午夜精品久久久久久久久 | 国产特级av| 久久久久久伦理 | 欧美破处女| 在线观看成年人视频 | gogo人体做爰大胆视频 | 一区在线免费观看 | 日本 奴役 捆绑 受虐狂xxxx | 91性色| 台湾佬美性中文 | 日韩在线一区二区三区四区 | 午夜视频在线观看一区二区 |