从MSAL2.5

时间:2018-11-22 00:34:32

标签: azure xamarin xamarin.forms azure-ad-b2c

我正在尝试在我的xamarin应用程序中使Azure AD B2C正常工作。检查我们是否已经登录,我正在使用如下代码。

  public async Task<bool> IsLoggedIn()
    {            
            IEnumerable<IAccount> accounts = await App.PCA.GetAccountsAsync();
            if (accounts != null)
            {
                return accounts.Any();
            }
            return false;
        }
    }

我在“开始”上的代码如下:

 protected async override void OnStart()
    {

            var authenticationService = Container.Resolve<IAuthenticationService>();
            bool isLoggedIn;

            isLoggedIn = await authenticationService.IsLoggedIn();

            if (isLoggedIn)
            {
                var cachingService = Container.Resolve<ICachingService>();

                AppUser = await authenticationService.Login(cachingService.CurrentMode);

                await NavigationService.NavigateAsync("http://www.xxxx.com/root/navigation/main");
            }
            else
            {
                await NavigationService.NavigateAsync("http://www.xxxx.com/navigation/login");
            }
        }           
    }

如果我只是从IsLoggedIn返回false,它将正确显示登录页面。 但是打电话

IEnumerable<IAccount> accounts = await App.PCA.GetAccountsAsync();

似乎有问题。

我有时会得到例外 System.NullReferenceException:对象引用未设置为对象的实例

但是在“ QuickWatch”中查看App对象时,我看到PAC对象已正确填充。

更新 App.cs构造函数如下所示

public static PublicClientApplication PCA = null;
 public App(IPlatformInitializer initializer = null) : base(initializer)
    {
        PCA = new PublicClientApplication(GlobalSetting.Instance.ClientID, GlobalSetting.Instance.AuthoritySignUpSignIn);
        PCA.RedirectUri = $"msal{GlobalSetting.Instance.ClientID}://auth";
    }

我的登录方法如下

    public async Task<User> Login(string mode)
    {
        IEnumerable<IAccount> accounts = await App.PCA?.GetAccountsAsync();
        AuthenticationResult ar;
        try
        {   //get token from cache.
            ar = await App.PCA?.AcquireTokenSilentAsync(GlobalSetting.Instance.Scopes, GetAccountByPolicy(accounts, GlobalSetting.Instance.PolicySignUpSignIn), GlobalSetting.Instance.AuthoritySignUpSignIn, false);
        }
        catch (MsalUiRequiredException ex)
        {
            // get token from interaction.
            ar = await App.PCA?.AcquireTokenAsync(GlobalSetting.Instance.Scopes, GetAccountByPolicy(accounts, GlobalSetting.Instance.PolicySignUpSignIn), App.UiParent);
        }
         //fetch token and make actual user object.
        return new User
            {
                Id = _cachingService.LoggedInUserId,
                Name = "Jessica Doe",
                ProfilePicUrl = "https://content-static.upwork.com/uploads/2014/10/01xxx27/profilephoto1.jpg",
                BusinessProfile = _userService.GetBusinessProfile(_cachingService.LoggedInUserId),
                ProfileVariables = _userService.GetUserProfileVariables(_cachingService.LoggedInUserId),
                Settings = _userService.GetSettings(_cachingService.LoggedInUserId)
            };

    }

当我不调用AcquireTokenSilentAsync并仅发送伪造的User对象时有效,而当我调用AcquireTokenSilentAsync时不起作用。 填充了ar对象,它导航到命中视图模型构造函数的主页,但显示空白页。

我还尝试了不同版本的MSAL。现在使用最新版本。

UPdate2

深入研究此异常

  

{Microsoft.Identity.Client.MsalClientException:该应用程序没有在Entitlements.plist中启用钥匙串访问组。结果,保存到iOS钥匙串失败。 Entitlements.plist中未启用钥匙串访问组“ 3G3LMCD5R.com.microsoft.adalcache”。有关启用钥匙串访问组和权利的更多详细信息,请参见https://aka.ms/msal-net-enable-keychain-groups。在Microsoft.Identity.Core.iOSTokenCacheAccessor中以0表示的Microsoft.Identity.Core.iOSTokenCacheAccessor.Save(System.String帐户,System.String服务,System.String泛型,System.Int32类型,System.String值)中的[0x00052]。 .SaveAccessToken(Microsoft.Identity.Core.Telemetry.TelemetryTokenCacheAccessor.SaveAccessToken的[0x00028]在:0中:: 0的Microsoft.Identity.Core.Telemetry.TelemetryTokenCacheAccessor.SaveAccessToken(在Microsoft.Identity.Core.Cache.MsalAccessTokenCacheItem项)[0x00000]在Microsoft.Identity.Client.TokenCache.SaveAccessAndRefreshToken(:0)中的Microsoft.Identity.Core.Telemetry.TelemetryTokenCacheAccessor.SaveAccessToken(Microsoft.Identity.Core.Cache.MsalAccessTokenCacheItem项,Microsoft.Identity.Core.RequestContext requestContext)[0x0002a] Microsoft.Identity.Core.Instance.IValidatedAuthoritiesCache validatedAuthoritiesCache,Microsoft.Identity.Core.Instance.IAadInstanceDiscovery aadInstanceDiscovery,Microsoft.Identity.Client.Internal.Requests.AuthenticationRequest在Microsoft.Identity.Client.Internal.Requests.RequestBase.CacheTokenResponseAndCreateAuthenticationResult(Microsoft.Identity.Core.OAuth2.MsalTokenResponse msalTokenResponse4)[0x00]中的参数requestParams,Microsoft.Identity.Core.OAuth2.MsalTokenResponse响应[0x00143] :0处Microsoft.Identity.Client.Internal.Requests.InteractiveRequest + d__9.MoveNext()的[0x00168] ---从Microsoft.Identity.Client抛出异常的先前位置开始的堆栈结束跟踪。 :0内的Internal.Requests.RequestBase + d__28.MoveNext()[0x00160] ---从上次引发异常的位置开始的堆栈跟踪结束--- Microsoft.Identity.Client.PublicClientApplication + d__24.MoveNext()[0x000ef :0中的] ---从上一个引发异常的位置开始的堆栈结束跟踪---在Microsoft.Identity.Client.PublicClientApplication + d__17.MoveNext()中:0中的---从上一个结束的堆栈结束跟踪在CDThat.Services.AzureA处引发异常的位置C:\ CDthatbest \ CDThat \ Services \ AzureADB2CAuthenticationService.cs:45中的DB2CAuthenticationService + d__3.MoveNext()[0x000fc] ---从上次引发异常的位置开始的堆栈跟踪---在CDThat.ViewModels.LoginPageViewModel + d__8 .MoveNext()在C:\ CDthatbest \ CDThat \ ViewModels \ LoginPageViewModel.cs:56中的[0x0003c] ---从上一个引发异常的位置开始的堆栈跟踪---在System.Runtime.CompilerServices.AsyncMethodBuilderCore + <> c .b__6_0(系统对象状态)[0x00000]在/Library/Frameworks/Xamarin.iOS.framework/Versions/12.2.1.11/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder中.cs:1023(位于Foundation.NSAsyncSynchronizationContextDispatcher.Apply()[0x00000]在/Library/Frameworks/Xamarin.iOS.framework/Versions/12.2.1.11/src/Xamarin.iOS/Foundation/NSAction.cs:178(包装器已管理) (到本机)UIKit.UIApplication.Main(系统上的UIKit.UIApplication.UIApplicationMain(int,string [],intptr,intptr))。 /Library/Frameworks/Xamarin.iOS.framework/Versions/12.2.1.11/src/Xamarin.iOS/UIKit/UIApplication.cs:79中的String [] args,System.IntPtr主体,System.IntPtr代理)[0x00005] UIKit.UIApplication.Main(/Library/Frameworks/Xamarin.iOS.framework/Versions/12.2.1.11/src/Xamarin.iOS/中的UIKit.UIApplication.Main(System.String [] args,System.StringPrincipalClassName,System.String proxyClassName)[0x0002c]在CDThat.iOS.Application.Main(System.String [] args)处的UIKit / UIApplication.cs:63(位于C:\ CDthatbest \ CDThat.iOS \ Main.cs:16错误代码:missing_entitlements}中的[0x00014]

1 个答案:

答案 0 :(得分:0)

这可能是一个计时问题(提早访问PCA属性)。我将首先更改代码以更优雅地处理空的PCA属性:

public async Task<bool> IsLoggedIn()
{            
        // Added a null check on the PCA property
        IEnumerable<IAccount> accounts = await App.PCA?.GetAccountsAsync();
        if (accounts != null)
        {
            return accounts.Any();
        }
        return false;
    }
}

然后尝试使用其他事件(例如PageAppearing)而不是OnStart来访问PCA属性。

希望有帮助!