Permission screen appears every time

六月ゝ 毕业季﹏ 提交于 2019-12-11 01:49:08

问题


I want to make my WinForms-App to use the SingleSign-On (SSO) feature with Microsoft Accounts.
I created a LiveApp and I'm able to Login to my App with the LiveSDK 5.4.
But everytime I click on my Login-Button the permissions list appears and I need to accept it again.

This is my code:

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));
        }
    }
}

What I need to change? I don't want the User to accept the permissions on each login.


回答1:


You can use IRefreshTokenHandler to save token as following example:

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);
        });
    }
}

after that you get session as following:

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);
    }
}



回答2:


I've only used this API in Objective C, but I had to follow two steps.

  1. Use the wl.offline_access scope. (Which you're already doing)
  2. You only show the login screen if the sessions object is null. If your session object is already populated, you can proceed as you would if the sign in was successful.


来源:https://stackoverflow.com/questions/18955426/permission-screen-appears-every-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!