question

ZSTTest-3233 avatar image
0 Votes"
ZSTTest-3233 asked ShwetaMathur commented

How to implement normal login and azure ad sso login in asp.net mvc?

I want an asp.net web application with SSO login and normal login. I have followed all the steps from the Microsoft Document (https://learn.microsoft.com/en-us/azure/active-directory/develop/web-app-quickstart?pivots=devlang-aspnet).

SSO login works fine but I was not able to login using normal login. If I revert the changes I made for the SSO login normal login works. I have combined the normal login and SSO login authentication integrated in startup.cs. When I do this, the Microsoft login goes on an loop mode signing in again and again.

I have attached my startup.cs file. Could anyone help me out?

I have tried using

 app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

before using

 app.UseOpenIdConnectAuthentication


My startup.cs file

 public void Configuration(IAppBuilder app) 
 {
     // The Client ID is used by the application to uniquely identify itself to Azure AD.
     string clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];
    
     // RedirectUri is the URL where the user will be redirected to after they sign in.
     string redirectUri = System.Configuration.ConfigurationManager.AppSettings["RedirectUri"];
    
     // Tenant is the tenant ID (e.g. contoso.onmicrosoft.com, or 'common' for multi-tenant)
     string tenant = System.Configuration.ConfigurationManager.AppSettings["Tenant"];
    
     // Authority is the URL for authority, composed by Microsoft identity platform endpoint and the tenant name (e.g. https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0)
     string authority = String.Format(System.Globalization.CultureInfo.InvariantCulture, System.Configuration.ConfigurationManager.AppSettings["Authority"], tenant);
    
     app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
    
     var timeoutInMinutes = Convert.ToDouble(ConfigurationManager.AppSettings["SessionExpireInMinutes"]);
    
     // Configure the db context, user manager and signin manager to use a single instance per request
     app.CreatePerOwinContext(ApplicationDbContext.Create);
     app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
     app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    
     app.UseCookieAuthentication(new CookieAuthenticationOptions
             {
                 AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                 LoginPath = new PathString("/Account/Login"),
                 Provider = new CookieAuthenticationProvider
                 {
                     // Enables the application to validate the security stamp when the user logs in.
                     // This is a security feature which is used when you change a password or add an external login to your account.  
                     OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                         validateInterval: TimeSpan.FromMinutes(30),
                         regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)),
                     OnResponseSignIn = context =>
                     {
                         context.Properties.IsPersistent = false;
                         context.Properties.AllowRefresh = true;
                         context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(timeoutInMinutes);
                     }
                 },
                 SlidingExpiration = true
             });
    
     app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
     // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
     app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));
    
     // Enables the application to remember the second login verification factor such as phone or email.
     // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
     // This is similar to the RememberMe option when you log in.
     app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);
                
     app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
             {                
                 AuthenticationMode = AuthenticationMode.Passive,
                 // Sets the client ID, authority, and redirect URI as obtained from Web.config
                 ClientId = clientId,
                 Authority = authority,
                 RedirectUri = redirectUri,
                 // PostLogoutRedirectUri is the page that users will be redirected to after sign-out. In this case, it's using the home page
                 PostLogoutRedirectUri = redirectUri,
                 Scope = OpenIdConnectScope.OpenIdProfile,
                 // ResponseType is set to request the code id_token, which contains basic information about the signed-in user
                 ResponseType = OpenIdConnectResponseType.CodeIdToken,
                 // ValidateIssuer set to false to allow personal and work accounts from any organization to sign in to your application
                 // To only allow users from a single organization, set ValidateIssuer to true and the 'tenant' setting in Web.config to the tenant name
                 // To allow users from only a list of specific organizations, set ValidateIssuer to true and use the ValidIssuers parameter
                 TokenValidationParameters = new TokenValidationParameters()
                 {
                     ValidateIssuer = false // Simplification (see note below)
                 },
                 // OpenIdConnectAuthenticationNotifications configures OWIN to send notification of failed authentications to the OnAuthenticationFailed method
                 Notifications = new OpenIdConnectAuthenticationNotifications
                 {
                     AuthenticationFailed = OnAuthenticationFailed
                 }
     });
 }
    
 /// <summary>
 /// Handle failed authentication requests by redirecting the user to the home page with an error in the query string
 /// </summary>
 /// <param name="context"></param>
 /// <returns></returns>
 private Task OnAuthenticationFailed(AuthenticationFailedNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
 {
     context.HandleResponse();
     context.Response.Redirect("/?errormessage=" + context.Exception.Message);
     return Task.FromResult(0);
 }




azure-active-directorydotnet-aspnet-mvcazure-ad-openid-connect
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @ZSTTest-3233,

Just checking in to see if the below answer helped. If this answers your query, please don’t forget to click "Accept the answer" and Up-Vote for the same, which might be beneficial to other community members reading this thread. And, if you have any further query do let us know.

Thanks,
Shweta


0 Votes 0 ·

1 Answer

ShwetaMathur avatar image
0 Votes"
ShwetaMathur answered

Hi @ZSTTest-3233,

Thanks for reaching out.

There might be few possible scenarios to avoid this issue:

1.Commenting out the below lines from above code, stooped the redirect loop.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});


2.This issue is because of the authentication mode selected by the MVC Template, which triggers the ReturnUrl Style of redirection that might lead to an infinite loop if not configured correctly.

To disable OWIN startup discovery, add this key to your webconfig file.

<add key="owin:AutomaticAppStartup" value="false"/>

3.You have to check AllowAnonymous and Authorize attribute in the controller containing login action and adding allowAnonymous might help to solve this issue.

4.Check the redirect URI has been configured correctly and not have extra '/' which is also the possible reason for redirect loop.

Hope this will help.

Thanks,
Shweta


Please remember to "Accept Answer" if answer helped you.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.