question

DmitriyReznik-4665 avatar image
0 Votes"
DmitriyReznik-4665 asked DmitriyReznik-4665 commented

Azure B2C authentication does not work with WebForms

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?

azure-ad-b2cdotnet-aspnet-webforms
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.

1 Answer

alfredorevilla-msft avatar image
0 Votes"
alfredorevilla-msft answered DmitriyReznik-4665 commented

Hello @dmitriyreznik-4665, 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.

· 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 @alfredorevilla-msft

Thank you for your answer. If I understand correctly, the missing part was commented out

     <authorization>
       <deny users="?" />
     </authorization>

But if I uncomment it, I get

Server Error in '/' Application.
Access is denied.
Description: An error occurred while accessing the resources required to serve this request. The server may not be configured for access to the requested URL.

Error message 401.2.: Unauthorized: Logon failed due to server configuration. Verify that you have permission to view this directory or page based on the credentials you supplied and the authentication methods enabled on the Web server. Contact the Web server's administrator for additional assistance.


Could you please advise if I did something wrong.

0 Votes 0 ·