自定义角色提供程序未被使用

时间:2017-12-28 19:50:17

标签: c# asp.net-mvc-5 windows-authentication roleprovider

好吧,所以我为我的网站创建了一个自定义角色提供程序,无论我做什么,我都无法获得被覆盖的函数中的代码以获得命中。

这是自定义角色提供程序

namespace XXX.Security
{
    using System;
    using System.Linq;
    using XXX.Areas.AccountManagement;
    using System.Web.Security;

    public class AppRoleProvider : RoleProvider
    {
        public override string ApplicationName
        {
            get
            {
                throw new NotImplementedException();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override void CreateRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            throw new NotImplementedException();
        }

        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            throw new NotImplementedException();
        }

        public override string[] GetAllRoles()
        {
            AccountManagementDbContext accountManagement = new AccountManagementDbContext("App Role Provider - GetAllRoles()");

            string[] roles = accountManagement.getRoles();

            return roles;
        }

        public override string[] GetRolesForUser(string username)
        {
            AccountManagementDbContext accountManagement = new AccountManagementDbContext("App Role Provider - GetRolesForUser()");

            string[] userRoles = accountManagement.getRolesForUser(username);

            return userRoles;
        }

        public override string[] GetUsersInRole(string roleName)
        {
            throw new NotImplementedException();
        }

        public override bool IsUserInRole(string username, string roleName)
        {
            AccountManagementDbContext accountManagement = new AccountManagementDbContext("App Role Provider - GetAllRoles()");

            string[] userRoles = accountManagement.getRolesForUser(username);

            return userRoles.Contains(roleName);
        }

        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            throw new NotImplementedException();
        }

        public override bool RoleExists(string roleName)
        {
            throw new NotImplementedException();
        }
    }
}

这是我的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=301880
  -->
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  </configSections>
  <connectionStrings>
    <add name="xxx"
         providerName="System.Data.SqlClient"
         connectionString="Data Source=xxx;
                           Initial Catalog=xxx;
                           Integrated Security=false;
                           User ID=xxx;
                           Password=xxx;"/>
  </connectionStrings>
  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="EnableSimpleMembership" value="false" />
  </appSettings>
  <system.web>
    <authentication mode="Windows" />
    <roleManager defaultProvider="AppRoleProvider" enabled="true">
      <providers>
        <clear/>
        <add name="AppRoleProvider" type="xxx.Security.AppRoleProvider"/>
      </providers>
    </roleManager>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" />
  </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthentication" />
      <remove name="TelemetryCorrelationHttpModule" />
      <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="integratedMode,managedHandler" />
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
    <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.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>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
    </providers>
  </entityFramework>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.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=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SqlServerCe.4.0" />
      <add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
    </DbProviderFactories>
  </system.data>
</configuration>

这是我正在使用的自定义授权属性

namespace XXX.Models
{
    using System.Web;
    using System.Web.Mvc;

    public class AccessDeniedAuthorizationAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            var user = HttpContext.Current.User.Identity.Name;

            if (filterContext.Result is HttpUnauthorizedResult)
            {               
                filterContext.Result = new RedirectResult("/AccessDenied");
            }
        }
    }
}

最后这是我的控制器

namespace XXX.Areas.Admin.Controllers
{
    using Models;
    using System.Web.Mvc;

    public class AdminController : Controller
    {
        [AccessDeniedAuthorization(Roles = "Administrator")]
        public ActionResult AdminHome()
        {
            var user = HttpContext.User.Identity.Name;
            return View();
        }
    }
}

所以这里有一些我试图让它起作用的事情......

尝试使用控制器操作上的默认授权属性。

尝试在我的web.config中为提供者指定其他属性,如此...

  <system.web>
    <authentication mode="Windows" />
    <roleManager defaultProvider="AppRoleProvider" enabled="true">
      <providers>
        <clear/>
        <add name="AppRoleProvider" type="XXX.Security.AppRoleProvider, XXX" connectionStringName="XXX"/>
      </providers>
    </roleManager>
    <compilation debug="true" targetFramework="4.6.1" />
    <httpRuntime targetFramework="4.6.1" />
  </system.web>

我从控制器中击中了角色提供程序中的所有重写函数,以确保它们正常工作,并且它们都正常工作并且达到了我在其中的断点。当我在自定义Authorization属性中设置断点时,虽然它在Admin控制器中的控制器操作被调用时命中。我甚至查看了HttpContext.Current.User.ProviderName,它是我的自定义角色提供程序的名称。

另一件奇怪的事情是,我的User.Identity永远不会填写我应该填充我的Windows登录信息,所以我想这将是一些问题,Windows身份验证不起作用。

我的项目属性中也启用了Windows身份验证。我还启用了匿名身份验证,因为我需要使用这两种身份验证。

还要把它扔出去。我的自定义角色提供程序位于我的Web项目中,但它引用的acccountmanagementdbcontext是在一个单独的项目中,但我看不出这会导致任何问题。

**更新** 我在Google上搜索有关更改IIS express的applicatonhost.config文件时发现了一些内容。

<windowsAuthentication enabled="true">
    <providers>
        <add value="Negotiate" />
        <add value="NTLM" />
    </providers>
</windowsAuthentication>

我这样做了,但仍然无效。

**更新2 ** 似乎由于某种原因,用户必须至少输入一次Windows凭证才能使Windows身份验证能够对其进行身份验证。我在本地运行时尝试使用我的Windows凭据,然后在输入凭据后,我的自定义角色提供程序中的代码被点击。

我的印象是,如果打开了Windows身份验证并且请求被发送到需要身份验证的控制器/操作,那么它只会自动提取Windows用户的凭据,然后将其传递给角色提供程序。

我的老板说,如果你和IIS服务器在同一个网络上,它会自动获取windows用户的凭据,但我有疑虑,因为我尝试在我的电脑上使用dns地址在我的电脑上托管这个我的主机文件仍然没有自动将我的Windows凭据填充到HttpContext.User.Identity中。

1 个答案:

答案 0 :(得分:0)

您必须使用Internet Explorer才能在站点启动时自动进行Windows身份验证。如果您使用IE访问该站点,将使用当前Windows用户名填充HttpContext.User.Identity.Name属性。我当时正在使用Firefox。这也是为什么我认为当我点击控制器动作时没有填充该属性是不正确的原因。在IE以外的任何浏览器中,您必须打开Windows身份验证,然后在尝试访问您已限制的站点区域时,在弹出登录框中输入Windows凭据。我禁用了登录弹出窗口,因此在我的网站中,当我尝试访问我设置为限制的控制器操作时,它从未通过Windows验证,因为如果没有在弹出登录中输入您的Windows凭据,则不会填充Identity.Name