【UWP】手動實現 WebAuthenticationBroker

来源:https://www.cnblogs.com/h82258652/archive/2019/04/09/10677504.html
-Advertisement-
Play Games

在 UWP 中,如果要進行 OAuth 授權,那很大概率是會用上 WebAuthenticationBroker 這個類的,例如微博授權這種。 在一般情況下來說,WebAuthenticationBroker 是足夠用的了,但是,如果你是碰上 Github 授權的話,那麼就會碰到這樣的情況: 蹦出一 ...


在 UWP 中,如果要進行 OAuth 授權,那很大概率是會用上 WebAuthenticationBroker 這個類的,例如微博授權這種。

在一般情況下來說,WebAuthenticationBroker 是足夠用的了,但是,如果你是碰上 Github 授權的話,那麼就會碰到這樣的情況:

Snipaste_2019-04-09_09-33-53

蹦出一大個警告,讓人看上去相當不爽。歸根的原因是 WebAuthenticationBroker 使用的是 IE 內核,這個我們可以通過 https://www.whatismybrowser.com/ 驗證。

Snipaste_2019-04-09_09-36-59

連 Edge 內核都不是,不給力啊,老濕。

 

那麼有沒有辦法把 WebAuthenticationBroker 換成 Edge 內核呢?簡單的辦法是沒有的了,但我們還有 WebView,WebView 是使用 Edge 內核的,可以通過 WebView 來手動實現我們自己的 WebAuthenticationBroker。

參考 WebAuthenticationBroker 類的 AuthenticateAsync,編寫如下代碼:

public static class MyWebAuthenticationBroker
    {
        public static Task<MyWebAuthenticationResult> AuthenticateAsync(Uri requestUri, Uri callbackUri)
        {
            throw new NotImplementedException();
        }
    }

WebAuthenticationBroker 的 AuthenticateAsync 這個方法有 3 個參數,但第一個參數並不是很常用,所以這裡就只使用後面的兩個參數了。另外因為 WebAuthenticationResult 沒有公共構造函數,所以定義一個 MyWebAuthenticationResult 來代替。

public class MyWebAuthenticationResult
    {
        public string ResponseData { get; internal set; }

        public uint ResponseErrorDetail { get; internal set; }

        public WebAuthenticationStatus ResponseStatus { get; internal set; }
    }

接下來就是如何實現的問題。這裡我們可以使用一個 ContentDialog 套 WebView 的方式。

在項目添加一個內容對話框(這裡我叫 AuthorizationDialog),並編寫如下代碼:

<ContentDialog x:Class="WebAuthenticationBrokerDemo.AuthorizationDialog"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
               Title="正在連接到服務"
               CloseButtonText="取消"
               FullSizeDesired="True"
               mc:Ignorable="d">
    <ContentDialog.Resources>
        <ResourceDictionary>
            <x:Double x:Key="ContentDialogMinWidth">800</x:Double>
        </ResourceDictionary>
    </ContentDialog.Resources>
    <Grid>
        <WebView x:Name="WebView"
                 NavigationFailed="WebView_NavigationFailed"
                 NavigationStarting="WebView_NavigationStarting" />
    </Grid>
</ContentDialog>

設置 FullSizeDesired 使高度占滿視窗,資源字典中覆蓋預設的對話框寬度。WebView 則訂閱 Starting 和 Failed 事件。編寫後臺 cs 代碼:

public sealed partial class AuthorizationDialog
    {
        private readonly Uri _callbackUri;

        public AuthorizationDialog(Uri requestUri, Uri callbackUri)
        {
            if (requestUri == null)
            {
                throw new ArgumentNullException(nameof(requestUri));
            }
            if (callbackUri == null)
            {
                throw new ArgumentNullException(nameof(callbackUri));
            }

            _callbackUri = callbackUri;

            InitializeComponent();

            WebView.Source = requestUri;
        }

        public Uri ResponseUri { get; private set; }

        public WebAuthenticationStatus Result { get; private set; } = WebAuthenticationStatus.UserCancel;

        public WebErrorStatus WebErrorStatus { get; private set; }

        private bool CheckUri(Uri uri)
        {
            if (uri.Host == _callbackUri.Host)
            {
                Result = WebAuthenticationStatus.Success;
                ResponseUri = uri;
                return true;
            }

            return false;
        }

        private void WebView_NavigationFailed(object sender, WebViewNavigationFailedEventArgs e)
        {
            if (CheckUri(e.Uri))
            {
                Hide();
                return;
            }

            Result = WebAuthenticationStatus.ErrorHttp;
            ResponseUri = e.Uri;
            WebErrorStatus = e.WebErrorStatus;
            Hide();
        }

        private void WebView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
        {
            if (CheckUri(args.Uri))
            {
                Hide();
            }
        }
    }

可以通過 Hide 方法來關閉對話框。需要註意的是 Failed 的時候需要先檢查一次,因為可能 callback 的地址是無法訪問的。

接下來可以補完一開始的 AuthenticateAsync 方法了。

public static class MyWebAuthenticationBroker
    {
        public static async Task<MyWebAuthenticationResult> AuthenticateAsync(Uri requestUri, Uri callbackUri)
        {
            var authorizationDialog = new AuthorizationDialog(requestUri, callbackUri);
            await authorizationDialog.ShowAsync();
            if (authorizationDialog.Result == WebAuthenticationStatus.UserCancel)
            {
                return new MyWebAuthenticationResult
                {
                    ResponseStatus = WebAuthenticationStatus.UserCancel
                };
            }
            else if (authorizationDialog.Result == WebAuthenticationStatus.Success)
            {
                return new MyWebAuthenticationResult
                {
                    ResponseStatus = WebAuthenticationStatus.Success,
                    ResponseData = authorizationDialog.ResponseUri.OriginalString
                };
            }
            else
            {
                return new MyWebAuthenticationResult
                {
                    ResponseStatus = WebAuthenticationStatus.ErrorHttp,
                    ResponseData = authorizationDialog.ResponseUri.OriginalString,
                    ResponseErrorDetail = (uint)authorizationDialog.WebErrorStatus
                };
            }
        }
    }

那麼現在我們再去連 Github 之類的授權就不會有警告了,因為內核已經換成了 Edge。

Snipaste_2019-04-09_15-56-26

而且因為是使用 WebView,所以還能再進行一些定製化的操作,例如執行 JavaScript,獲取 Cookie 之類的。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 每種方法中上面的是Excel的行數,下麵的是Excel的列數。方法七:經過加工修改已經可以讀出來的是有效數據行 using Excel = Microsoft.Office.Interop.Excel;//Excel表讀寫 Excel.Application app = new Excel.Appl ...
  • 原文鏈接:https://www.entityframeworktutorial.net/code-first/stringlength-dataannotations-attribute-in-code-first.aspx StringLength特性可以應用於實體的string類型的屬性上,它 ...
  • 原文鏈接:https://www.entityframeworktutorial.net/code-first/maxlength-minlength-dataannotations-attribute-in-code-first.aspx MaxLength特性指定了屬性的值所允許的最大值,然後在 ...
  • 最近在學WebSocket,服務端需要監聽多個WebSocket客戶端發送的消息。 開始的解決方法是每個WebSocket客戶端都添加一個線程進行監聽,代碼如下: /// <summary> /// 監聽埠 創建WebSocket /// </summary> /// <param name="h ...
  • 備註:本人使用開發工具:VS2017,.NET Core 2.2,其中VS2017原本自帶2.1,我單獨從官網下載了2.2的程式集安裝包,但是沒有下配套的運行環境,運行項目時出了一個問題。 以下是我在發佈Core項目後部署到IIS後運行時遇到的一些問題: 1-發佈設置: 在發佈過程中,項目一直還原n ...
  • [CommandMethod("CBline")] //對稱畫線 public void CBline() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor edit = doc.Editor; Databa ...
  • 主要代碼: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using GrxCAD.Runtime;using GrxCAD ...
  • 基於浩辰CAD2019 需求: 開發線轉圓簡單命令。命令過程:1) 請選擇圖中直線(要求支持一次選多個):2) 彈出對話框,輸入圓的圖層名和半徑3) 點對話框中確定按鈕,結束命令。命令執行效果:所選每條直線的起點和終點處,自動生成兩個圓;同時,所有直線自動整體平移MOVE一個向量AcGeVector ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...