每次都会出现权限屏幕

2024-04-01

我想让我的 WinForms 应用程序使用 Microsoft 帐户的单点登录 (SSO) 功能。
我创建了一个LiveApp https://account.live.com/developers/applications我可以使用 LiveSDK 5.4 登录我的应用程序。
但每次我单击登录按钮时,都会出现权限列表,我需要再次接受它。

这是我的代码:

private const string ClientID = "{MY_CLIENT_ID}";
private LiveAuthClient liveAuthClient;
private LiveConnectClient liveConnectClient;
string[] scopes = new string[] { "wl.offline_access", "wl.emails", "wl.signin" };

private void buttonLogin_Click(object sender, EventArgs e)
{
    liveAuthClient = new LiveAuthClient(ClientID);
    webBrowser1.Navigate(liveAuthClient.GetLoginUrl(scopes));
}

private async void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
    if (this.webBrowser1.Url.AbsoluteUri.StartsWith("https://login.live.com/oauth20_desktop.srf"))
    {
        AuthResult authResult = new AuthResult(this.webBrowser1.Url);
        if (authResult.AuthorizeCode != null)
        {
            try
            {
                LiveConnectSession session = await liveAuthClient.ExchangeAuthCodeAsync(authResult.AuthorizeCode);
                this.liveConnectClient = new LiveConnectClient(session);
                LiveOperationResult meRs = await this.liveConnectClient.GetAsync("me");
                dynamic meData = meRs.Result;
                if(string.Equals(meData.emails.account, MyAppUser.EmailAddress))
                    MessageBox.Show("Successful login: " + meData.name);
            }
            catch (LiveAuthException aex)
            {
                MessageBox.Show("Failed to retrieve access token. Error: " + aex.Message);
            }
            catch (LiveConnectException cex)
            {
                MessageBox.Show("Failed to retrieve the user's data. Error: " + cex.Message);
            }
        }
        else
        {
            MessageBox.Show(string.Format("Error received. Error: {0} Detail: {1}", authResult.ErrorCode, authResult.ErrorDescription));
        }
    }
}

我需要改变什么?我不希望用户每次登录时都接受权限。


您可以使用IRefreshTokenHandler保存令牌,如下例:

public class RefreshTokenHandler : IRefreshTokenHandler
{
    private string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\oneDrive\\RefreshTokenHandler\\RefreshTokenInfo.RefreshToken-me";
    public Task<RefreshTokenInfo> RetrieveRefreshTokenAsync()
    {
        return Task.Factory.StartNew<RefreshTokenInfo>(() =>
        {
            if (File.Exists(path))
            {
                return new RefreshTokenInfo(File.ReadAllText(path));
            }
            return null;
        });
    }

    public Task SaveRefreshTokenAsync(RefreshTokenInfo tokenInfo)
    {
        // Note: 
        // 1) In order to receive refresh token, wl.offline_access scope is needed.
        // 2) Alternatively, we can persist the refresh token.
        return Task.Factory.StartNew(() =>
        {
            if (File.Exists(path)) File.Delete(path);
            if (!Directory.Exists(Path.GetDirectoryName(path))) Directory.CreateDirectory(Path.GetDirectoryName(path));
            File.AppendAllText(path, tokenInfo.RefreshToken);
        });
    }
}

之后您将获得如下会话:

RefreshTokenHandler handler = new RefreshTokenHandler();
liveAuthClient = new LiveAuthClient(ClientID, handler);
var Session = liveAuthClient.InitializeAsync(scopes).Result.Session;
if (Session == null)
{
    webBrowser1.Navigate(liveAuthClient.GetLoginUrl(scopes));
}
else
{
    try
    {
        this.liveConnectClient = new LiveConnectClient(Session);
        LiveOperationResult meRs = await this.liveConnectClient.GetAsync("me");
        dynamic meData = meRs.Result;
        if (string.Equals(meData.emails.account, MyAppUser.EmailAddress))
            MessageBox.Show("Successful login: " + meData.name);
    }
    catch (LiveAuthException aex)
    {
        MessageBox.Show("Failed to retrieve access token. Error: " + aex.Message);
    }
    catch (LiveConnectException cex)
    {
        MessageBox.Show("Failed to retrieve the user's data. Error: " + cex.Message);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

每次都会出现权限屏幕 的相关文章

  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l

随机推荐

  • strcpy 到 mmap 地址返回总线错误

    我创建了一个进程 它调用设置了 MAP SHARED 标志的 mmap 当我尝试将字符串复制到该地址时 我收到总线错误核心转储 有人可以解释一下其背后的原因以及如何修复它 以下是我的代码 int main int fd 0 char ret
  • 停止/启动远程 Windows 服务并等待其打开/关闭

    最高答案这个问题 https stackoverflow com questions 187836 how do i restart a service on a remote machine in windows告诉我如何停止 启动远程服
  • Android 工具栏标题

    无法更改工具栏标题我在其中设置了标题manifeast xml 还使用了setTitle TITLE 我将标题设置为历史与报告但它显示不同的标题通知这是另一个活动标题 我检查了manifeast xml但没有变化 任何人都可以帮助我吗 这是
  • Python3.8 - FastAPI 和无服务器 (AWS Lambda) - 无法处理发送到 api 端点的文件

    我已经通过 AWS Lambda 函数将 FastAPI 与无服务器结合使用几个月了 效果非常好 我正在创建一个新的 api 端点 它需要发送一个文件 在我的本地计算机上使用时它工作得很好 但是当我部署到 AWS Lambda 时 当我尝试
  • 让SVM在Python中运行得更快

    使用code下面是 python 中的 svm from sklearn import datasets from sklearn multiclass import OneVsRestClassifier from sklearn svm
  • 使用 NumPy/SciPy 进行向量值函数插值

    有没有办法使用向量值函数进行插值NumPy http en wikipedia org wiki NumPy SciPy http en wikipedia org wiki SciPy 有很多适用于标量值函数的产品 我想我可以使用其中之一
  • Retrofit 将对象数组转换为 GSON 错误

    我正在使用 Retrofit 发出 HTTP 请求 该请求返回一个对象数组 但出现以下错误 com google gson JsonSyntaxException java lang IllegalStateException Expect
  • 播放wav文件c#代码

    如何在另一台电脑上播放 wav 文件 我知道我必须将 wav 文件作为输出设备上的缓冲区发送 有人可以用 C 给出一个简短的 eq 吗 您需要使用 Flash 或 Silverlight 在浏览器中播放音频 您不需要重新发明轮子 此外 除了
  • Linux 上使用 C/C++ 编写的简单原始套接字服务器

    我正在尝试使用原始套接字构建以太网 我无法使用 TCP IP UDP 或任何其他协议 这是因为它将与非常简单的硬件进行通信 这些硬件没有资源来处理所有不同的协议层 我的网络将由一台主机组成 通过以太网交换机与多个硬件进行通信 此时 我基本上
  • 通过 google 模块进行 Python 搜索给出 SSL: CERTIFICATE_VERIFY_FAILED 错误

    我在 Mac OSX 上使用 Python 3 python3 版本给出 Python 3 6 3 我安装了certifi已经包了 python 3 m pip install certifi回馈 Requirement already s
  • 在 NetBeans 快捷方式中注释/取消注释代码块

    NetBeans 中是否有快捷方式可以突出显示代码块并对其进行注释 取消注释 Try this combination in the Netbeans Editor ctrl shift c
  • cookie 值应该进行 URL 编码吗?

    设置 cookie 时 PHP 对 cookie 值进行 url 编码 至少在不使用时 setrawcookie 它对 cookie 值进行 url 解码在将其提供给应用程序之前 COOKIE 这是公认的标准吗 如果我将原始 cookie
  • 如何根据多个字段删除SQL表中的重复项

    我有一张游戏桌 描述如下 Field Type Null Key Default Extra id int 11 NO PRI NULL auto increment date date NO NULL
  • Rails ActionMailer 忽略environment.rb 中的设置

    我把我的 ActionMailer 配置放在我的config environment rb像这样的文件 MyApp Application initialize MyApp Application configure do config a
  • 黄瓜无法加载 2.1/gherkin_lexer_en

    每当我运行黄瓜功能时 我都会收到以下错误 但是 该脚本工作正常 但每次执行功能文件时都会出现此警告消息 这里有什么问题吗 C Automation PickLists Activities 2 RemoveActivity gt cucum
  • 函数中的变量

    我看到了下面的代码 第一次调用 next num 回报1 第二个返回2 define next num let num 0 lambda set num num 1 num next num 1 next num 2 我无法理解的是 num
  • JavaFX 中的字段验证[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我使用 fxml 创建了一份注册表单 现在我想实现字段验证功能 我正在尝试实现 TextField 的验证 但仍然没有得到它 不幸的是
  • CSS(位置:绝对+左:50%=最大宽度:50%)?

    我正在开发一个网站 但遇到了临时问题 我有一个div with CSS像这样 box position absolute width auto max width 75 left 50 transform translate 50 0 ms
  • Rails:如何添加目标空白的 link_to

    我是 Rails 3 的新手 我想将 target gt blank 添加到下面的 link to helper link to GOOGLE http www google com class btn btn large btn prim
  • 每次都会出现权限屏幕

    我想让我的 WinForms 应用程序使用 Microsoft 帐户的单点登录 SSO 功能 我创建了一个LiveApp https account live com developers applications我可以使用 LiveSDK