c# - 如何解决SSRS "Could not load Authorization extension"异常?

标签 c# reporting-services ssrs-2012

我正在尝试为 SSRS 2014 实现自定义身份验证,但无法让它工作。

我所做的是登录页面。我可以看到登录页面,并且我可以(某种程度上)成功登录。当我输入错误的凭据时,它会保留在登录页面上。当我输入有效凭据时,我将被重定向到 /Reports/Pages/Folder.aspx 或在报表服务器的情况下重定向到 /

但是我在日志中看到异常:无法加载授权扩展:

日志文件:

ui!ReportServer_0-1!4f4!08/06/2016-09:16:40:: e ERROR: Software Usage Metrics initialize failed
library!ReportServer_0-1!4f4!08/06/2016-09:16:41:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: Could not load Authorization extension, Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: The report server has encountered a configuration error. ;
appdomainmanager!ReportManager_0-2!1654!08/06/2016-09:16:43:: i INFO: RS authentication mode is 16; effective ASP.NET authentication mode is Forms. vdir=/Reports.
ui!ReportManager_0-2!1654!08/06/2016-09:16:43:: e ERROR: Software Usage Metrics initialize failed
library!ReportServer_0-1!3468!08/06/2016-09:16:48:: i INFO: Call to GetPermissionsAction(/).
library!ReportServer_0-1!3468!08/06/2016-09:16:48:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: Could not load Authorization extension, Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: The report server has encountered a configuration error. ;
ui!ReportManager_0-2!1654!08/06/2016-09:16:48:: e ERROR: System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: The report server has encountered a configuration error.  ---> Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: The report server has encountered a configuration error. 
   at Microsoft.ReportingServices.Library.ReportingService2005Impl.GetPermissions(String Item, String[]& Permissions)
   at Microsoft.ReportingServices.WebServer.ReportingService2010.GetPermissions(String ItemPath, String[]& Permissions)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at Microsoft.SqlServer.ReportingServices2010.ReportingService2010.GetPermissions(String ItemPath)
   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.<>c__DisplayClass3e.<GetPermissions>b__3d()
   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)
   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod()
   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.GetPermissions(String itemPath)
   at Microsoft.ReportingServices.UI.Permissions.GetPermissions()
   at Microsoft.ReportingServices.UI.Permissions.CurrentUser(String itemPath)
   at Microsoft.ReportingServices.UI.ReportingPage.get_RSUser()
   at Microsoft.ReportingServices.UI.FolderPage.Page_Init(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Web.UI.Control.OnInit(EventArgs e)
   at System.Web.UI.Page.OnInit(EventArgs e)
   at System.Web.UI.Control.InitRecursive(Control namingContainer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
library!ReportServer_0-1!954!08/06/2016-09:16:48:: i INFO: Call to GetSystemPermissionsAction().
library!ReportServer_0-1!954!08/06/2016-09:16:48:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: Could not load Authorization extension, Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: The report server has encountered a configuration error. ;
ui!ReportManager_0-2!1654!08/06/2016-09:16:48:: e ERROR: HTTP status code --> 200
-------Details--------
System.Web.Services.Protocols.SoapException: System.Web.Services.Protocols.SoapException: The report server has encountered a configuration error.  ---> Microsoft.ReportingServices.Diagnostics.Utilities.ServerConfigurationErrorException: The report server has encountered a configuration error. 
   at Microsoft.ReportingServices.Library.ReportingService2005Impl.GetPermissions(String Item, String[]& Permissions)
   at Microsoft.ReportingServices.WebServer.ReportingService2010.GetPermissions(String ItemPath, String[]& Permissions)

   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)

   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

   at Microsoft.SqlServer.ReportingServices2010.ReportingService2010.GetPermissions(String ItemPath)

   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.<>c__DisplayClass3e.<GetPermissions>b__3d()

   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)

   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod()

   at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.GetPermissions(String itemPath)

   at Microsoft.ReportingServices.UI.Permissions.GetPermissions()

   at Microsoft.ReportingServices.UI.Permissions.CurrentUser(String itemPath)

   at Microsoft.ReportingServices.UI.ReportingPage.get_RSUser()

   at Microsoft.ReportingServices.UI.FolderPage.Page_Init(Object sender, EventArgs e)

   at System.EventHandler.Invoke(Object sender, EventArgs e)

   at System.Web.UI.Control.OnInit(EventArgs e)

   at System.Web.UI.Page.OnInit(EventArgs e)

   at System.Web.UI.Control.InitRecursive(Control namingContainer)

   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
library!ReportServer_0-1!3468!08/06/2016-09:16:48:: i INFO: Call to GetSystemPropertiesAction().
ui!ReportManager_0-2!1654!08/06/2016-09:16:49:: e ERROR: System.Threading.ThreadAbortException: Thread was being aborted.
   at System.Threading.Thread.AbortInternal()
   at System.Threading.Thread.Abort(Object stateInfo)
   at System.Web.HttpResponse.End()
   at Microsoft.ReportingServices.UI.ReportingPage.ShowErrorPage(String errMsg)

rsreportserver.config:

<Authentication>
    <AuthenticationTypes>
        <Custom />
    </AuthenticationTypes>
    <EnableAuthPersistence>true</EnableAuthPersistence>
    <RSWindowsExtendedProtectionLevel>Off</RSWindowsExtendedProtectionLevel>
    <RSWindowsExtendedProtectionScenario>Proxy</RSWindowsExtendedProtectionScenario>
</Authentication>

...

<UI>
    <CustomAuthenticationUI>
        <loginUrl>/Logon.aspx</loginUrl>
        <UseSSL>False</UseSSL>
        <PassThroughCookies>
            <PassThroughCookie>sqlAuthCookie</PassThroughCookie>
        </PassThroughCookies>
    </CustomAuthenticationUI>
    <ReportServerUrl>http://localhost/ReportServer</ReportServerUrl>
</UI>

...

<!-- Under Extensions tag -->
<Security>
    <Extension Name="Forms" Type="SsrsCustomAuthWeb.SsrsAuth.SsrsCustomAuthentication, SsrsCustomAuthWeb" >
        <Configuration>
            <AdminConfiguration>
                <UserName>Martijn</UserName>
            </AdminConfiguration>
        </Configuration>
    </Extension>
</Security>
<Authentication>
    <Extension Name="Forms" Type="SsrsCustomAuthWeb.SsrsAuth.SsrsCustomAuthentication, SsrsCustomAuthWeb"/>
</Authentication>

报表服务器的web.config:

 <authentication mode="Forms">
  <forms loginUrl="Logon.aspx" name="sqlAuthCookie" timeout="60" path="/"/>
</authentication>
<authorization> 
    <deny users="?" />
</authorization>

ReportManager 的 web.config

 <authentication mode="Forms">
</authentication>

SsrsCustomAuthentication.cs

public class SsrsCustomAuthentication : IAuthenticationExtension
{
    public string LocalizedName
    {
        get
        {
            return null;
        }
    }

    public void GetUserInfo(out IIdentity userIdentity, out IntPtr userId)
    {
        userIdentity = HttpContext.Current.User.Identity;
        userId = IntPtr.Zero;
    }

    public bool IsValidPrincipalName(string principalName)
    {
        return true;
    }

    public bool LogonUser(string userName, string password, string authority)
    {
        if (userName == "Martijn")
            return true;

        return false;
    }

    public void SetConfiguration(string configuration)
    {

    }
}

授权.cs

public class Authorization : IAuthorizationExtension
{
    private static string m_adminUserName;
    static Authorization()
    {
        InitializeMaps();
    }

    public byte[] CreateSecurityDescriptor(AceCollection acl, SecurityItemType itemType, out string stringSecDesc)
    {
        // Creates a memory stream and serializes the ACL for storage.
        BinaryFormatter bf = new BinaryFormatter();
        using (MemoryStream result = new MemoryStream())
        {
            bf.Serialize(result, acl);
            stringSecDesc = null;
            return result.GetBuffer();
        }
    }

    public bool CheckAccess(string userName,IntPtr userToken,byte[] secDesc, ModelItemOperation modelItemOperation)
    {
        if (0 == String.Compare(userName, m_adminUserName, true,CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true,CultureInfo.CurrentCulture))
            {
                foreach (ModelItemOperation aclOperation in ace.ModelItemOperations)
                {
                    if (aclOperation == modelItemOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public bool CheckAccess( string userName,IntPtr userToken, byte[] secDesc,ModelOperation modelOperation)
    {
        if (0 == String.Compare(userName, m_adminUserName, true, CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true, CultureInfo.CurrentCulture))
            {
                foreach (ModelOperation aclOperation in ace.ModelOperations)
                {
                    if (aclOperation == modelOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public bool CheckAccess(string userName,IntPtr userToken,byte[] secDesc,CatalogOperation requiredOperation)
    {
        if (0 == String.Compare(userName, m_adminUserName, true, CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true,CultureInfo.CurrentCulture))
            {
                foreach (CatalogOperation aclOperation in ace.CatalogOperations)
                {
                    if (aclOperation == requiredOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public bool CheckAccess(string userName,IntPtr userToken, byte[] secDesc,CatalogOperation[] requiredOperations)
    {
        foreach (CatalogOperation operation in requiredOperations)
        {
            if (!CheckAccess(userName, userToken, secDesc, operation))
                return false;
        }
        return true;
    }

    public bool CheckAccess(string userName, IntPtr userToken,byte[] secDesc,ReportOperation requiredOperation)
    {
        // If the user is the administrator, allow unrestricted access.
        if (0 == String.Compare(userName, m_adminUserName, true,CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true,CultureInfo.CurrentCulture))
            {
                foreach (ReportOperation aclOperation in ace.ReportOperations)
                {
                    if (aclOperation == requiredOperation)
                        return true;
                }
            }
        }
        return false;
    }

    public bool CheckAccess(string userName,IntPtr userToken,byte[] secDesc,FolderOperation requiredOperation)
    {
        // If the user is the administrator, allow unrestricted access.
        if (0 == String.Compare(userName, m_adminUserName, true,CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true, CultureInfo.CurrentCulture))
            {
                foreach (FolderOperation aclOperation in ace.FolderOperations)
                {
                    if (aclOperation == requiredOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public bool CheckAccess(string userName, IntPtr userToken,  byte[] secDesc, FolderOperation[] requiredOperations)
    {
        foreach (FolderOperation operation in requiredOperations)
        {
            if (!CheckAccess(userName, userToken, secDesc, operation))
                return false;
        }
        return true;
    }

    public bool CheckAccess( string userName,IntPtr userToken,  byte[] secDesc, ResourceOperation requiredOperation)
    {
        // If the user is the administrator, allow unrestricted access.
        if (0 == String.Compare(userName, m_adminUserName, true,  CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true, CultureInfo.CurrentCulture))
            {
                foreach (ResourceOperation aclOperation in ace.ResourceOperations)
                {
                    if (aclOperation == requiredOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public bool CheckAccess(string userName, IntPtr userToken,byte[] secDesc, ResourceOperation[] requiredOperations)
    {
        // If the user is the administrator, allow unrestricted access.
        if (0 == String.Compare(userName, m_adminUserName, true, CultureInfo.CurrentCulture))
            return true;

        foreach (ResourceOperation operation in requiredOperations)
        {
            if (!CheckAccess(userName, userToken, secDesc, operation))
                return false;
        }
        return true;
    }

    public bool CheckAccess( string userName, IntPtr userToken, byte[] secDesc, DatasourceOperation requiredOperation)
    {
        // If the user is the administrator, allow unrestricted access.
        if (0 == String.Compare(userName, m_adminUserName, true, CultureInfo.CurrentCulture))
            return true;

        AceCollection acl = DeserializeAcl(secDesc);
        foreach (AceStruct ace in acl)
        {
            if (0 == String.Compare(userName, ace.PrincipalName, true,CultureInfo.CurrentCulture))
            {
                foreach (DatasourceOperation aclOperation in ace.DatasourceOperations)
                {
                    if (aclOperation == requiredOperation)
                        return true;
                }
            }
        }

        return false;
    }

    public StringCollection GetPermissions(string userName, IntPtr userToken,SecurityItemType itemType, byte[] secDesc)
    {
        StringCollection permissions = new StringCollection();
        if (0 == String.Compare(userName, m_adminUserName, true,CultureInfo.CurrentCulture))
        {
            foreach (CatalogOperation oper in m_CatOperNames.Keys)
            {
                if (!permissions.Contains((string)m_CatOperNames[oper]))
                    permissions.Add((string)m_CatOperNames[oper]);
            }
            foreach (ModelItemOperation oper in m_ModelItemOperNames.Keys)
            {
                if (!permissions.Contains((string)m_ModelItemOperNames[oper]))
                    permissions.Add((string)m_ModelItemOperNames[oper]);
            }
            foreach (ModelOperation oper in m_ModelOperNames.Keys)
            {
                if (!permissions.Contains((string)m_ModelOperNames[oper]))
                    permissions.Add((string)m_ModelOperNames[oper]);
            }
            foreach (CatalogOperation oper in m_CatOperNames.Keys)
            {
                if (!permissions.Contains((string)m_CatOperNames[oper]))
                    permissions.Add((string)m_CatOperNames[oper]);
            }
            foreach (ReportOperation oper in m_RptOperNames.Keys)
            {
                if (!permissions.Contains((string)m_RptOperNames[oper]))
                    permissions.Add((string)m_RptOperNames[oper]);
            }
            foreach (FolderOperation oper in m_FldOperNames.Keys)
            {
                if (!permissions.Contains((string)m_FldOperNames[oper]))
                    permissions.Add((string)m_FldOperNames[oper]);
            }
            foreach (ResourceOperation oper in m_ResOperNames.Keys)
            {
                if (!permissions.Contains((string)m_ResOperNames[oper]))
                    permissions.Add((string)m_ResOperNames[oper]);
            }
            foreach (DatasourceOperation oper in m_DSOperNames.Keys)
            {
                if (!permissions.Contains((string)m_DSOperNames[oper]))
                    permissions.Add((string)m_DSOperNames[oper]);
            }
        }
        else
        {
            AceCollection acl = DeserializeAcl(secDesc);
            foreach (AceStruct ace in acl)
            {
                if (0 == String.Compare(userName, ace.PrincipalName, true, CultureInfo.CurrentCulture))
                {
                    foreach (ModelItemOperation aclOperation in ace.ModelItemOperations)
                    {
                        if (!permissions.Contains((string)m_ModelItemOperNames[aclOperation]))
                            permissions.Add((string)m_ModelItemOperNames[aclOperation]);
                    }
                    foreach (ModelOperation aclOperation in ace.ModelOperations)
                    {
                        if (!permissions.Contains((string)m_ModelOperNames[aclOperation]))
                            permissions.Add((string)m_ModelOperNames[aclOperation]);
                    }
                    foreach (CatalogOperation aclOperation in ace.CatalogOperations)
                    {
                        if (!permissions.Contains((string)m_CatOperNames[aclOperation]))
                            permissions.Add((string)m_CatOperNames[aclOperation]);
                    }
                    foreach (ReportOperation aclOperation in ace.ReportOperations)
                    {
                        if (!permissions.Contains((string)m_RptOperNames[aclOperation]))
                            permissions.Add((string)m_RptOperNames[aclOperation]);
                    }
                    foreach (FolderOperation aclOperation in ace.FolderOperations)
                    {
                        if (!permissions.Contains((string)m_FldOperNames[aclOperation]))
                            permissions.Add((string)m_FldOperNames[aclOperation]);
                    }
                    foreach (ResourceOperation aclOperation in ace.ResourceOperations)
                    {
                        if (!permissions.Contains((string)m_ResOperNames[aclOperation]))
                            permissions.Add((string)m_ResOperNames[aclOperation]);
                    }
                    foreach (DatasourceOperation aclOperation in ace.DatasourceOperations)
                    {
                        if (!permissions.Contains((string)m_DSOperNames[aclOperation]))
                            permissions.Add((string)m_DSOperNames[aclOperation]);
                    }
                }
            }
        }

        return permissions;
    }

    private AceCollection DeserializeAcl(byte[] secDesc)
    {
        AceCollection acl = new AceCollection();
        if (secDesc != null)
        {
            BinaryFormatter bf = new BinaryFormatter();
            using (MemoryStream sdStream = new MemoryStream(secDesc))
            {
                acl = (AceCollection)bf.Deserialize(sdStream);
            }
        }
        return acl;
    }

    private static Hashtable m_ModelItemOperNames;
    private static Hashtable m_ModelOperNames;
    private static Hashtable m_CatOperNames;
    private static Hashtable m_FldOperNames;
    private static Hashtable m_RptOperNames;
    private static Hashtable m_ResOperNames;
    private static Hashtable m_DSOperNames;

    private const int NrRptOperations = 27;
    private const int NrFldOperations = 10;
    private const int NrResOperations = 7;
    private const int NrDSOperations = 7;
    private const int NrCatOperations = 16;
    private const int NrModelOperations = 11;
    private const int NrModelItemOperations = 1;

   private static void InitializeMaps()
    {
        // Perform initialization of some hash maps
    }

   public void SetConfiguration(string configuration)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(configuration);
        if (doc.DocumentElement.Name == "AdminConfiguration")
        {
            foreach (XmlNode child in doc.DocumentElement.ChildNodes)
            {
                if (child.Name == "UserName")
                {
                    m_adminUserName = child.InnerText;
                }
                else
                {
                    throw new Exception(string.Format(CultureInfo.InvariantCulture, "Unrecognized configuration element."));
                }
            }
        }
        else
            throw new Exception(string.Format(CultureInfo.InvariantCulture, "Root element is not \"AdminConfiguration\" in config data."));
    }

     public string LocalizedName
    {
        get
        {
            return null;
        }
    }
}

最佳答案

我终于明白了。最后发现我在 rsreportserver.config 中犯了一个非常微妙的配置错误:

Security 标记中指定的类型必须是实现 IAuthorizationExtension 接口(interface)的类的类型。

Extension 标记(在Authentication 标记下)中指定的类型是实现IAuthenticationExtension 接口(interface)的类的名称。在这里我想错了。这里我有一个实现了 IAuthorizationExtension 的类。

关于c# - 如何解决SSRS "Could not load Authorization extension"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38801935/

相关文章:

c# - Xamarin Forms 条目中的删除线文本

c# - 报告服务器 Web 服务在哪里

visual-studio - SSRS - 参数 - SELECT ALL 与 ALL - 如何删除 ALL 选项

reporting-services - 如何为 SSRS 中的所有报表订阅设置一个中央位置?

visual-studio-2012 - SSRS 导出到 Excel 会创建额外的列

c# - 如何在 asp.net web 应用程序 (C#) 中制作倒数计时器?

C# 测试汇编

c# - 使用 ObservableCollection 绑定(bind) WPF DataGrid Combobox 列的问题

SQL Server/SSRS : Calculating monthly average based on grouping and historical values

sql - 当数据是多种格式的混合时,如何使用 2 位数字来格式化 SSRS 字段