2

我想让我的 WinForms-App 使用 Microsoft 帐户的 SingleSign-On (SSO) 功能。
我创建了一个LiveApp,并且可以使用 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));
        }
    }
}

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

4

2 回答 2

2

您可以使用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);
    }
}
于 2014-06-10T14:08:54.893 回答
0

我只在 Objective C 中使用过这个 API,但我必须遵循两个步骤。

  1. 使用 wl.offline_access 范围。(你已经在做)
  2. 如果会话对象为空,则仅显示登录屏幕。如果您的会话对象已被填充,您可以像登录成功时一样继续操作。
于 2014-02-28T22:43:55.880 回答