ServiceStack MicrosoftGraphAuthProvider in MVC Controller produces no roles

Viewed 101

We have the following authentication setup for our ServiceStack MVC implementation

    public void Configure(IAppHost appHost)
    {
        var AppSettings = appHost.AppSettings;

        var providers = new IAuthProvider[] {
                new ServiceStack.Auth.NetCoreIdentityAuthProvider(AppSettings),
                new MicrosoftGraphAuthProvider(AppSettings),
                ConfigureJwtAuthProviderReader(appHost),
            };          

        var authFeature = new AuthFeature(() => new AuthUserSession(), providers)
        {   
            IncludeAssignRoleServices = false,
            IncludeRegistrationService = false
        };

        appHost.Plugins.Add(authFeature);
    }

    private JwtAuthProviderReader ConfigureJwtAuthProviderReader(IAppHost appHost)
    {
        var settings = new AzureAdOptions();
        appHost.GetConfiguration().Bind("AzureAd", settings);
        var jwt = settings.GetJWTProviderReader(appHost.Config.DebugMode);

        jwt.PopulateSessionFilter = (session, payload, request) =>
        {
            var upn = payload.GetValueOrDefault("upn") ?? string.Empty;
            var uniqueName = payload.GetValueOrDefault("unique_name");
            var appid = payload.GetValueOrDefault("appid");
            session.Email ??= (upn.Contains("@", StringComparison.InvariantCultureIgnoreCase) ? upn : null);
            session.UserName ??= uniqueName ?? appid ?? string.Empty;
            if (string.IsNullOrWhiteSpace(session.DisplayName))
            {
                session.DisplayName = session.UserName;
            }

            session.DisplayName = System.Text.RegularExpressions.Regex.Unescape(session.DisplayName);
        };
        return jwt;
    }

In our mvc controller

    this.AuthUser.Roles

is an empty collection for all users authenticating via MicrosoftGraphAuthProvider. It is however populated for users using ConfigureJwtAuthProviderReader.

EDIT: See comment from @DeonHeyns for solution

1 Answers

Can you use a custom MicrosoftGraphAuthProvider and override OnAuthenticatedAsync() and update your answer with the JSON info contained in MS Auth Token? i.e.

public class MyMicrosoftAuthProvider : MicrosoftGraphAuthProvider
{
    public MyMicrosoftAuthProvider(IAppSettings appSettings) : base(appSettings) {}

    public override Task<IHttpResult> OnAuthenticatedAsync(
        IServiceBase authService, IAuthSession session, 
        IAuthTokens tokens, Dictionary<string, string> authInfo,
        CancellationToken token = default)
    {
        var json = authInfo.ToJson(); //What's in this?
        json.Print();
        return base.OnAuthenticatedAsync(authService, session, tokens, authInfo, token);
    }
}
Related