Base solution for your next web application
Open Closed

Microsoft/Azure Active Directory Login in Login page along with sql login #7422


User avatar
0
botcoredev created

Hi,

Requirement : Login with Microsoft/Azure AD Users as an option in Login page. **Trails: ******

  1. Using App Registration in Azure Active Directory.https://docs.microsoft.com/en-us/azure/app-service/configure-authentication-provider-microsoft
  2. Using Open ID Connect. https://docs.aspnetzero.com/documents/aspnet-core-mvc/latest/Infrastructure-Core-Mvc-Identity-Server4-Integration

Please help me for sign in to Azure AD/ Microsoft.

Thanks in Advance.


17 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @botcoredev

    OpenID Connect can help you I guess. Which template do you use, JQuery, Angular 8 ? I assume you are using ASP.NET Core version.

  • User Avatar
    0
    botcoredev created

    Yes, I am using Asp .Net Core MVC with JQuery.

    I configured the Identitysrever config along with openID Connect config.

    After making openID=> IsEnabled "true", I am getting the "openId" button in login page. On click its not redirecting to O365 login page as it supposed to be.

    As checked, the (href="#") is like this for openIdConnect button.

    I configured all the details for OpenId in appsettings.json. According to documents it is supposed to working.

    Here is my configs:

    "OpenId": { "IsEnabled": "true", "Authority": "https://login.microsoftonline.com/xxxxxxxxxTenentIDxxxxxxxx", "LoginUrl": "https://login.microsoftonline.com/xxxxxxxxxTenentIDxxxxxxxx/oauth2/authorize", "ClientId": "xxxxxxxxxClientIDxxxxxxxx", "ClientSecret": "xxxxxxxxxClientSecretxxxxxxxx", "ValidateIssuer": "false", "ClaimsMapping": [ { "claim": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "key": "http://schemas.microsoft.com/identity/claims/objectidentifier" } ] }

    Here is the portion in Login.cshtml, where "openidconnect" button is getting rendered.

                @foreach (var p in loginProviders)
                {
                    <a href="#" class="btn btn-outline-secondary kt-btn btn-sm">
                        <i class="fab fa-@getSocialIconClass(p.DisplayName)"></i>
                        @p.DisplayName
                    </a>
                }
                
    

    What am I doing wrong, can you please help me solve this. Because its very important feature, which needs to be integrated for our product.

    Thanks in advance.

  • User Avatar
    0
    botcoredev created

    Hi @ismcagdas,

    Please can help me with this because I followed the docs, but in there they haven't explained it properly.

    I am in a hurry. Please respond as soon as you can.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Could you make the change below in your project and try again ?

  • User Avatar
    0
    CrayonGroupSCA created

    Hi,

    I'm also trying this as well.

    Adding the "social-login-icon" for me now makes the "OpenIdConnect" button submit when on login screen as a tenant, however the AccountController > ExternalLogin "provider" value is null as the hidden form input has no value. Should the hidden "provider" pass a value as well?

    Thanks, Dave

  • User Avatar
    0
    botcoredev created

    Hi @ismcagdas,

    After adding the "social-login-icon" class to the <a>, it became a button, but it always returns to the login page only. "http://localhost:62114/Account/Login?ReturnUrl=%2FAccount%2FExternalLoginCallback%3FReturnUrl%3D%252FAdminPortal"

    As @Dave asked do we need to pass some value for "provider"?

    Thanks in advance.

  • User Avatar
    0
    CrayonGroupSCA created

    This post (https://support.aspnetzero.com/QA/Questions/7453#answer-6ed4fe11-90b5-7a96-4b14-39ef7dc96d8f) had an extra snippet to add in for the link to set the provider. With that in place I had a provider passed but the returnUrl wasn't matching the expected return urls set in Azure Portal.

    <br>

    <a href="javascript:;" data-provider="@p.DisplayName" class="btn btn-outline-secondary kt-btn btn-sm social-login-icon">
        <i class="fab fa-@getSocialIconClass(p.DisplayName)"></i>
        @p.DisplayName
    </a>
    

    Currently for testing I'm hard coding the returnUrl with the "/signin-oidc" which appears in the Azure AD url as the returnUrl. Adding that in to the Portal then gets me one step further to AD related issues and registering a user.

    public ActionResult ExternalLogin(string provider, string returnUrl, string ss = "") { returnUrl = "http://localhost:62114/signin-oidc";

    Dave

  • User Avatar
    0
    CrayonGroupSCA created

    A quick update. After changing my Reply URLs in Azure Portal AD App to the below (note the * as we are using sub domains for tenants) I've now removed my hard coded returnURL shown above and am letting it use the default "/App" set elsewhere in code.

    Azure AD wasn't returning the EmailAddress claim type, but did have a preferred_username which was the email address for my AD user. To work around this it I tweaked the below code in DefaultExternalLoginInfoManager.cs to check for the Email claim first and then check for "preferred_username" as a fall back.

    This got me to the stage that the OpenIdConnect button works and a user can then set their name / surname / email based on the provided AD login and get to the welcome screen with a banner.

    Hopefully this will help you progress your code, and can update as necessary for any official tweaks for the above workarounds (quite nice to this).

    Dave

  • User Avatar
    0
    botcoredev created

    Hi @CrayonGroupSCA,

    I did the changes as you mentioned, and its working upto a point where NewUser needs to be registered.

        public virtual string GetUserNameFromClaims(List&lt;Claim&gt; claims)
        {
    		if (claims.Where(x => x.Type == ClaimTypes.Email).Any())
    		{
    			return claims.First(c => c.Type == ClaimTypes.Email)?.Value.ToMd5();
    		}
    		else if (claims.Where(x => x.Type == "preferred_username").Any())
    		{
    			return claims.First(c => c.Type == "preferred_username")?.Value.ToMd5();
    		}
    
    		return null;
            //return claims.First(c => c.Type == ClaimTypes.Email)?.Value.ToMd5();
        }
        
    

    here I am not getting the email as you suggested.

    After that I am getting redirected to "Register" page where I am entering the email and then click register.

    Then it goes to Register() in line no: 446 in Account controller, from there it navigates to UserRegistrationManager.cs >>> RegisterAsync() >> in line no 78 : user.SetNormalizedNames(); and throws an error.

    please help me resolve this and i am good to go.

    And thank you very much guys.

  • User Avatar
    0
    CrayonGroupSCA created

    Can you add the email address you attempted to log in with to the Users screen in Azure AD as a Guest user. See if that helps from values being passed back, otherwise a guess would be not all the values in that model are populated but I didn't edit anything else than the above.

  • User Avatar
    0
    botcoredev created

    Hi @CrayonGroupSCA ,

    I solved the issue.

    public virtual string GetUserNameFromClaims(List<Claim> claims) { if (claims.Where(x => x.Type == ClaimTypes.Email).Any()) { return claims.First(c => c.Type == ClaimTypes.Email)?.Value.ToMd5(); } else if (claims.Where(x => x.Type ==** ClaimTypes.Name**).Any()) { return claims.First(c => c.Type == ClaimTypes.Name)?.Value.ToMd5(); }

    		return null;
    		//return claims.First(c => c.Type == ClaimTypes.Email)?.Value.ToMd5();
    	}
    

    Its running perfectly now.

    Lot of thanks guys.

  • User Avatar
    0
    botcoredev created

    Hi @CrayonGroupSCA,

    All the configurations working for localhost, but it throws an error in production.

    I am able to register a user in localhost, but in production it throw an error. Please look into below pic:

    I am able to get authenticated in o3665, but after that when it ask to register, it trows this error.

    this is the console error. Please help me solve this.

    Thanks in Advance.

  • User Avatar
    0
    CrayonGroupSCA created

    I never had that issue when trying to set it up in our enviroment. All I can think of is do you have SMTP settings in place in production in case it is trying to sent an email.

    Perhaps check the internal Audit Logs table to see if the platform is providing any exception message.

    Otherwise you'll need to wait for the official support to see if they have any ideas :)

    Dave

  • User Avatar
    0
    botcoredev created

    Hi @CrayonGroupSCA and ismcagdas,

    I used remote debugging, and found out the error comes in UserRegistrationManager.cs >> RegisterAsync(string name, string surname, string emailAddress, string userName, string plainPassword, bool isEmailConfirmed, string emailActivationLink):

            await _userManager.InitializeOptionsAsync(AbpSession.TenantId);
            CheckErrors(await _userManager.CreateAsync(user, plainPassword));
            await CurrentUnitOfWork.SaveChangesAsync();
            
    

    line no : 86,87,88

    here it cannot able to get create the new user. I am getting all the values for user. But still it throws an error.

    Here is the plain password:

    as you can notice its getting all the values but still unable to create new user and throws error.

  • User Avatar
    0
    botcoredev created

    Please guys help me resolve this becoz, I happen to notice this for production env only. Locally its working as expected.

    Thanks in advance.

  • User Avatar
    0
    botcoredev created

    Hi Guys,

    I happened to find out that, I cant even able to register a normal user in the website.

    In the register.cshtml page it showing this:

    What's happening, can somebody please explain to me, what it is.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @botcoredev

    I'm sorry for the late response. You need to use a configuration for your website for recaptcha, see https://developers.google.com/recaptcha/docs/domain_validation. After getting SiteKey and SecretKey, replace the values in appsettings.json with your values.