如何解决SSRS“无法加载授权扩展”异常?

时间:2016-08-06 07:58:34

标签: c# reporting-services ssrs-2012

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

我的工作是登录页面。我可以看到登录页面,我可以(有点)成功登录。当我输入错误的凭据时,它将保留在登录页面上。当我输入有效凭据时,我被重定向到/Reports/Pages/Folder.aspx,或者如果报告服务器被重定向到/

但后来我在日志中看到了一个例外:Could not load Authorization extension

日志文件:

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>

ReportServer的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)
    {

    }
}

Authorization.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;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

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

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

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