Azure B2C authentication does not work with WebForms

Dmitriy Reznik 236 Reputation points
2022-07-15T21:19:50.967+00:00

I have an Asp.Net 4.7 WebForms legacy application written in vb.net. I need to add Azure B2C authentication. So I registred an app with Azure, and added OWIN middleware NuGet packages, and made all necessary configuration changes. I expect to see the log in screen when the application runs, and yet it does not happen. The application just runs without any authentication.
To narrow down the problem, I created a completely new WebForms application with Asp.Net 4.7 and vb.net. But the result was the same.

Here is the code:

Startup.vb

Imports System.Threading.Tasks  
Imports Microsoft.IdentityModel.Protocols.OpenIdConnect  
Imports Microsoft.IdentityModel.Tokens  
Imports Microsoft.Owin.Security  
Imports Microsoft.Owin.Security.Cookies  
Imports Microsoft.Owin.Security.Notifications  
Imports Microsoft.Owin.Security.OpenIdConnect  
Imports Owin  
  
Public Class Startup  
    Private Shared clientId As String = ConfigurationManager.AppSettings("ida:ClientId")  
    Private Shared aadInstance As String = ConfigurationManager.AppSettings("ida:AadInstance")  
    Private Shared tenant As String = ConfigurationManager.AppSettings("ida:Tenant")  
    Private Shared redirectUri As String = ConfigurationManager.AppSettings("ida:RedirectUri")  
    'Public Shared SignUpPolicyId As String = ConfigurationManager.AppSettings("ida:SignUpPolicyId")  
    'Public Shared ProfilePolicyId As String = ConfigurationManager.AppSettings("ida:UserProfilePolicyId")  
    Public Shared SignInPolicyId As String = ConfigurationManager.AppSettings("ida:SignInPolicyId")  
  
    Public Sub Configuration(ByVal app As IAppBuilder)  
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)  
        app.UseCookieAuthentication(New CookieAuthenticationOptions())  
        'app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignUpPolicyId))  
        'app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(ProfilePolicyId))  
        app.UseOpenIdConnectAuthentication(CreateOptionsFromPolicy(SignInPolicyId))  
        'app.UseStageMarker(PipelineStage.Authenticate)  
    End Sub  
  
    Private Function AuthenticationFailed(ByVal notification As AuthenticationFailedNotification(Of OpenIdConnectMessage, OpenIdConnectAuthenticationOptions)) As Task  
        notification.HandleResponse()  
  
        If notification.Exception.Message = "access_denied" Then  
            notification.Response.Redirect("/")  
        Else  
            notification.Response.Redirect("/Home/Error?message=" & notification.Exception.Message)  
        End If  
  
        Return Task.FromResult(0)  
    End Function  
  
    Private Function CreateOptionsFromPolicy(ByVal policy As String) As OpenIdConnectAuthenticationOptions  
        Dim options = New OpenIdConnectAuthenticationOptions With {  
            .MetadataAddress = String.Format(aadInstance, tenant, policy),  
            .AuthenticationType = policy,  
            .ClientId = clientId,  
            .RedirectUri = redirectUri,  
            .PostLogoutRedirectUri = redirectUri,  
            .Notifications = New OpenIdConnectAuthenticationNotifications With {  
                .AuthenticationFailed = AddressOf AuthenticationFailed  
            },  
            .Scope = "openid",  
            .ResponseType = "id_token",  
            .TokenValidationParameters = New TokenValidationParameters With {  
                .NameClaimType = "name"  
            }  
        }  
        Return options  
    End Function  
End Class  
  

Web.config

<?xml version="1.0" encoding="utf-8"?>  
<!--  
  For more information on how to configure your ASP.NET application, please visit  
  https://go.microsoft.com/fwlink/?LinkId=169433  
  -->  
<configuration>  
  <system.web>  
		<authentication mode="None" />  
    <compilation debug="true" strict="false" explicit="true" targetFramework="4.7" />  
    <httpRuntime targetFramework="4.7" />  
    <pages>  
      <namespaces>  
        <add namespace="System.Web.Optimization" />  
      </namespaces>  
      <controls>  
        <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />  
      </controls>  
    </pages>  
  </system.web>  
	<appSettings>  
		<!-- Azure AD B2C Settings -->  
		<add key="ida:Tenant" value="laticreteb2c.onmicrosoft.com" />  
		<add key="ida:ClientId" value="1eb04f44-f85d-4a2d-b170-fdaa0b2dc467" />  
		<add key="ida:AadInstance" value="https://login.microsoftonline.com/{0}/v2.0/.well-known/openid-configuration?p={1}" />  
		<add key="ida:RedirectUri" value="https://localhost:44379/signin-oidc" />  
		<!--<add key="ida:SignUpPolicyId" value="<<signup-policy-name>>" />-->  
		<add key="ida:SignInPolicyId" value="B2C_1_signin" />  
		<!--<add key="ida:UserProfilePolicyId" value="<<editprofile-policy-name>>" />-->  
	</appSettings>  
  <runtime>  
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
      <dependentAssembly>  
        <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />  
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />  
      </dependentAssembly>  
      <dependentAssembly>  
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />  
        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />  
      </dependentAssembly>  
      <dependentAssembly>  
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />  
        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />  
      </dependentAssembly>  
    </assemblyBinding>  
  </runtime>  
  <system.codedom>  
    <compilers>  
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />  
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />  
    </compilers>  
  </system.codedom>  
</configuration>  

The execution comes to the Configuration() method, and yet it doesn't help. What am I missing?

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,254 questions
Microsoft Entra External ID
Microsoft Entra External ID
A modern identity solution for securing access to customer, citizen and partner-facing apps and services. It is the converged platform of Azure AD External Identities B2B and B2C. Replaces Azure Active Directory External Identities.
2,639 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. 2022-07-17T02:13:21.45+00:00

    Hello @Dmitriy Reznik , your web.config (don't pay attention to appSettings) should look similar to this:

       <?xml version="1.0"?>  
       <!--  
         For more information on how to configure your ASP.NET application, please visit  
          https://go.microsoft.com/fwlink/?LinkId=301880  
         
         -->  
       <configuration>  
         <location path="Account">  
           <system.web>  
             <authorization>  
               <allow users="*"/>  
             </authorization>  
           </system.web>  
         </location>  
         <!--  
           For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.  
         
           The following attributes can be set on the <httpRuntime> tag.  
             <system.Web>  
               <httpRuntime targetFramework="4.7" />  
             </system.Web>  
         -->  
         <system.web>  
           <authorization>  
             <deny users="?"/>  
           </authorization>  
           <authentication mode="None"/>  
           <compilation debug="true" targetFramework="4.7"/>  
           <httpRuntime targetFramework="4.7"/>  
           <pages>  
             <namespaces>  
               <add namespace="System.Web.Optimization"/>  
             </namespaces>  
             <controls>  
               <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt"/>  
             </controls>  
           </pages>  
         </system.web>  
         <system.webServer>  
           <modules>  
             <remove name="FormsAuthentication"/>  
           </modules>  
         </system.webServer>  
         <runtime>  
           <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
             <dependentAssembly>  
               <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f"/>  
               <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35"/>  
               <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35"/>  
               <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35"/>  
               <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>  
               <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35"/>  
               <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0"/>  
             </dependentAssembly>  
             <dependentAssembly>  
               <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35"/>  
               <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930"/>  
             </dependentAssembly>  
           </assemblyBinding>  
         </runtime>  
         <system.codedom>  
           <compilers>  
             <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>  
             <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+"/>  
           </compilers>  
         </system.codedom>  
         <appSettings>  
           <add key="ida:ClientId" value="c1874cf1-a4e5-4af1-bd43-b13f59dfbee3"/>  
           <add key="ida:MetadataAddress" value="https://alfredorevillaatmsftb.b2clogin.com/tfp/alfredorevillaatmsftb.onmicrosoft.com/B2C_1_SI/v2.0/.well-known/openid-configuration"/>  
           <add key="ida:RedirectUri" value="https://localhost:44321/signin-oidc"/>  
         </appSettings>  
       </configuration>  
    

    Let us know if you need additional assistance. If the answer was helpful, please accept it and complete the quality survey so that others can find a solution.