Pergunta

I have run into a strange issue. I'm using Forms Authentication and Active Directory. I'm using a custom ADRolesProvider to use the groups from the AD. However, I have just realized if I try to log in, no matter what the login credentials are, after two attempts I'm able to log in as " " which is just a space. I'm not sure how to stop this and what to even consider where the problem lies. Here is my Web.config.

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="ADService" connectionString="LDAP://domain/OU=stores,DC=domaincontroller,DC=net" />
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-CentralLogin-20131227090301;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-CentralLogin-20131227090301.mdf" />

    <add name="DBConnection" connectionString="Data Source=server;Initial Catalog=db;Integrated Security=True" providerName="System.Data.SqlClient" />

  </connectionStrings>
  <system.web>
    <customErrors mode="On" defaultRedirect="~/ErrorPages/Oops.aspx">
      <error statusCode="401" redirect="~/ErrorPages/UnauthorizedAccess.aspx"/>
      <error statusCode="403" redirect="~/ErrorPages/Forbidden.aspx"/>
      <error statusCode="404" redirect="~/ErrorPages/PageNotFound.aspx" />
      <error statusCode="406" redirect="~/ErrorPages/NoAcceptab le.aspx" />
      <error statusCode="412" redirect="~/ErrorPages/PreconditionFailed.aspx" />
      <error statusCode="500" redirect="~/ErrorPages/InternalServerError.aspx" />
      <error statusCode="501" redirect="~/ErrorPages/NotImplemented.aspx" />
      <error statusCode="502" redirect="~/ErrorPages/BadGateway.aspx" />
    </customErrors>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <pages>
      <namespaces>
        <add namespace="System.Web.Optimization" />
      </namespaces>
      <controls>
        <add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt" />
        <add tagPrefix="ajaxToolkit" assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" />
      </controls>
    </pages>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" name="ADAuthCookie" timeout="60" defaultUrl="~/Dashboard.aspx" />
    </authentication>
    <sessionState timeout="60" mode="InProc" cookieless="false" />
    <machineKey validationKey="F4C71E2764B15C6" decryptionKey="058908ECF9ABEA546C9F626E" validation="SHA1" decryption="AES" />
    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
      <providers>
        <clear />
        <!--Membership provider for Active Directory-->
        <add name="AspNetActiveDirectoryMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider,  System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="ADService" attributeMapUsername="sAMAccountName" />
      </providers>
    </membership>
    <roleManager enabled="true" defaultProvider="ADRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookiePath="/" cookieTimeout="60" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All">
      <providers>
        <clear />
        <add name="ADRoleProvider" connectionStringName="ADConnectionString" connectionUsername="username" connectionPassword="password" attributeMapUsername="sAMAccountName" type="ActiveDirectoryRoleProvider"/>
      </providers>
    </roleManager>
  </system.web>
  <location path="Dashboard.aspx">
    <system.web>
      <authorization>
        <deny users="?" />
      </authorization>
    </system.web>
  </location>
  <location path="About.aspx">
    <system.web>
      <authorization>
        <deny users="?" />
      </authorization>
    </system.web>
  </location>
  <location path="Reporting/Payroll/StorePayroll.aspx">
    <system.web>
      <authorization>
        <allow roles="SoftwareDevelopers,IntranetManagers"/>
        <deny users="*" />
      </authorization>
    </system.web>
  </location>
  <system.webServer>
    <httpErrors existingResponse="Replace">
      <remove statusCode="502" subStatusCode="-1" />
      <remove statusCode="501" subStatusCode="-1" />
      <remove statusCode="500" subStatusCode="-1" />
      <remove statusCode="412" subStatusCode="-1" />
      <remove statusCode="406" subStatusCode="-1" />
      <remove statusCode="405" subStatusCode="-1" />
      <remove statusCode="403" subStatusCode="-1" />
      <remove statusCode="401" subStatusCode="-1" />
      <remove statusCode="404" subStatusCode="-1" />
      <!--redirects to error pages -->
    </httpErrors>
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" />
        <bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.WindowsAzure.Storage" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.1.0.4" newVersion="2.1.0.4" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="AjaxMin" publicKeyToken="21ef50ce11b5d80f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.6.5100.19196" newVersion="5.6.5100.19196" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

Login

  public partial class Login : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (User.Identity.IsAuthenticated)
            {
                Response.Redirect("~/Dashboard.aspx");
            }

            Response.CacheControl = "No-cache";
            SetFocus(Login1.FindControl("UserName"));
        }

        protected void btnLogin_Click(object sender, EventArgs e)
        {
            FormsAuthentication.SetAuthCookie(User.Identity.Name.ToString(), false);
        }
    }

Any help is appreciated. If anymore information is needed, let me know!

UPDATE: How I solved the problem with Wiktor Zychla suggestion.

placed this within button click.

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "TheDomain"))
        {
            // validate the credentials
            bool isValid = pc.ValidateCredentials("myuser", "mypassword", ContextOptions.Negotiate);

            if (IsValid == false)
            {
                FormsAuthentication.SetAuthCookie(User.Identity.Name.ToString(), false);
            }
        }

I thought the isValid == true would work but it didn't. However the isValid == false did work so I'm rolling with it.

Foi útil?

Solução

  FormsAuthentication.SetAuthCookie(User.Identity.Name.ToString(), false);

sets the authentication cookie. There is no if before it! This means that the first time you cause this event, you unconditionally authenticate the user which is authenticated so far. And who is? No one, thus " ".

This means that you issue forms cookie to empty username. Second time the page is submitted, the cookie is in the request so that forms module correctly recognizes authenticated user.

What you want is something like

    protected void btnLogin_Click(object sender, EventArgs e)
    {
        if ( username_password_pair_is_correct ) 
           FormsAuthentication.SetAuthCookie(User.Identity.Name.ToString(), false);
    }

where the actual condition should verify the pair against the AD (it is not difficult and googing will help you).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top