我正在尝试为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;
}
}
}
答案 0 :(得分:3)
我终于明白了。最后我发现我在rsreportserver.config中做了一个非常微妙的配置错误:
Security
标记中指定的类型必须是实现IAuthorizationExtension
接口的类的类型。
Extension
标记(Authentication
标记下)中指定的类型是实现IAuthenticationExtension
接口的类的名称。在这里,我想错了。在这里,我有一个实现IAuthorizationExtension
的课程。