Base solution for your next web application

Activities of "cmthomps"

Answer

I'd be happy to share what I have. One piece of additional info. The line of code with the authSchema parameter came from a Asp.Net Boilerplate project. I had downloaded it when I was having problems to try a different set of code. The AspNetZero project I downloaded does not use the authSchema.

Here is a link to a gist that allowed me to login with a Core 1.0/1.1 AspNetZero project. It represents a change to the AuthConfigurer.cs. I don't think this change is necessary for .NET Core 2.0 based AspNetZero projects.

https://gist.github.com/cmthomps/53645f3ca5f7af3feebb8f4766c6362d
Answer

Update on this thread. I finally got all my issues ironed out. But, I'm confused a bit. I downloaded a new .NET Core/jQuery solution from aspnetzero.com on 10/24. In that version, the AccountController.cs has the following method:

[UnitOfWork]
        public virtual async Task<ActionResult> ExternalLoginCallback(string returnUrl, string authSchema, string remoteError = null)
        {
            returnUrl = NormalizeReturnUrl(returnUrl);
            
            if (remoteError != null)
            {
                Logger.Error("Remote Error in ExternalLoginCallback: " + remoteError);
                throw new UserFriendlyException(L("CouldNotCompleteLoginOperation"));
            }

            var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(authSchema);
            if (externalLoginInfo == null)
            {
                Logger.Warn("Could not get information from external login.");
                return RedirectToAction(nameof(Login));
            }

            await _signInManager.SignOutAsync();

            var tenancyName = GetTenancyNameOrNull();

            var loginResult = await _logInManager.LoginAsync(externalLoginInfo, tenancyName);

            switch (loginResult.Result)
            {
                case AbpLoginResultType.Success:
                    await _signInManager.SignInAsync(loginResult.Identity, false);
                    return Redirect(returnUrl);
                case AbpLoginResultType.UnknownExternalLogin:
                    return await RegisterForExternalLogin(externalLoginInfo);
                default:
                    throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
                        loginResult.Result,
                        externalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email) ?? externalLoginInfo.ProviderKey,
                        tenancyName
                    );
            }
        }

The problematic line of code was:

var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync(authSchema);

The authSchema parameter was what was causing the problem. When running with OpenId, that parameter has a value of "OpenIdConnect". However, in digging into the underlying MSFT code that parameter is:

<param name="expectedXsrf">Flag indication whether a Cross Site Request Forgery token was expected in the current request.</param>

When I removed the parameter from GetExternalLoginInfoAsync, the authentication started working. The thing that is baffling to me is that in looking at the code currently on GitHub, that parameter is not there... Not exactly sure what is going on. The code on GitHub looks right but it's different from what I downloaded via aspnetzero.com the other day.

Hope this helps someone else...

Answer

That would be great. I'd appreciate it. I downloaded the latest version (4.6) of aspnetzero for this test because I was wondering if the version we were working with had a bug. I'm not sure what version of abp comes with 4.6. I'd be happy to send you my test project as well.

Answer

Thank you. I'm seeing the same result with Azure OpenId Connect GetExternalLoginInfoAsync returns null but I see similar cookies to the screenshot in my previous post.

Answer

One more piece of information, after I get the null result in my previous post. The application redirects to login. When I look at the cookies, I see what is in the attached image. Something is coming back from the OpenId Connect server. Just not sure where the issue is.

Answer

I've tried another OpenId server. With both Okta and Auth0, in the ExternalLoginCallback method in the AccountController this line of code come back with a null result. Google works. But any of the openId connect servers I've tried doesn't.

var externalLoginInfo = await _signInManager.GetExternalLoginInfoAsync();
Answer

Same result. I had already had those same settings in my appsettings.json file (this is a core project). The openid login redirects to the proper openId authority but after I login, I get the "invalid_grant - A redirect_uri can only be used by implicit or authorization_code grant types." error on the openid server (not in my aspnetzero project).

"OpenId": {
      "IsEnabled": "true",
      "Authority": "https://sb-auth.smarthealthit.org/",
      "ClientId": "4*******",
      "ClientSecret": "********"
    }

I finally figured it out. I was trying to use an async method in the AppNotifier class. When I changed the method to be non-async, the notifications started going through. (Not just on the first pass through the service).

Thanks. Still no luck. I'm still seeing that the notification goes through the first time the service is hit but not on subsequent passes. Here is what my code looks like now. Happy to send in the project if it helps. It's a test project.

using Abp;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Runtime.Session;
using System.Linq;
using TestCode.TestCode.Authorization.Users;

namespace TestCode.TestCode.Notifications
{
    public class NotificationDomainService : TestCodeDomainServiceBase, INotificationDomainService
    {
        //private readonly INotificationDomainService _notificationDomainService;

        private readonly IAppNotifier _appNotifier;
        private readonly UserManager _userManager;
        private IRepository<User, long> _userRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IAbpSession _session;

        public NotificationDomainService(IAppNotifier appNotifier, IRepository<User, long> userRepository, IUnitOfWorkManager unitOfWorkManager, IAbpSession abpSession)//, UserManager userManager)
        {
            _appNotifier = appNotifier;
            //_userManager = userManager;
            _userRepository = userRepository;
            _unitOfWorkManager = unitOfWorkManager;
            _session = abpSession;
        }


        public virtual void NotifyAllForTenantById(int? tenantId, string message = "Domain Service", string severity = "info")
        {
            using (_session.Use(tenantId, null))
            {
                using (var unitOfWork = _unitOfWorkManager.Begin())
                {

                    using (CurrentUnitOfWork.DisableFilter(AbpDataFilters.MayHaveTenant))
                    {

                        var users = _userRepository.GetAllList(u => u.TenantId == tenantId);
                        //UserIdentifier[] userIds = new UserIdentifier[users.Count()];
                        int i = 0;
                        foreach (User u in users)
                        {
                            UserIdentifier userId = new UserIdentifier(tenantId, u.Id);
                            //userIds[i] = userId;
                            _appNotifier.SendMessageAsync(userId, "Hello to All Tenant Users From The Domain Service " + System.DateTime.Now.ToLongTimeString());
                        }
                        //_appNotifier.SendAlertToAllTenantUsersAsync("Hello to All Tenant Users From The Domain Service", userIds);

                        CurrentUnitOfWork.SaveChanges();
                    }

                    unitOfWork.Complete();
                }
            }
        }


    }
}

No errors. Consistently, the first time the service runs, the notification gets sent and received. After that, none of the other notifications go through. The hangfire jobs show success. Screenshot attached,

Showing 41 to 50 of 59 entries