📄 securitymanager.cs
字号:
using System;
using System.Web;
using System.Collections;
using System.Collections.Specialized;
using Microsoft.Interop.Security.AzRoles;
using System.Diagnostics;
using System.Threading;
using System.Security.Principal;
using System.Configuration;
using AWC.Reporter.Web.Entities;
namespace AWC.Reporter.Web.EnterpriseReporting.Security
{
/// <summary>
/// The Authorization Manager implementation of Security Services
/// </summary>
public class SecurityManager: MarshalByRefObject
{
/// <summary>
/// Holds a reference to the Application store
/// </summary>
private static _application = null;
/// <summary>
/// The name of the application
/// </summary>
private static string _applicationName = null;
/// <summary>
/// Static constructor
/// </summary>
/// <remarks>
/// Initializes the application store
/// </remarks>
static SecurityManager()
{
IAzAuthorizationStore authorizationStore = new AzAuthorizationStoreClass();
string authorizationStorePath = @"msxml://" + ConfigurationSettings.AppSettings[Constants.CONFIG_AZMAN_CONFIG_STORE];
try
{
// open the AzMan configuration store
authorizationStore.Initialize(0, authorizationStorePath, null);
}
catch (System.Runtime.InteropServices.COMException ex)
{
throw new ApplicationException (String.Format("Can't initialize IAzAuthorizationStore {0}.", authorizationStore), ex);
}
try
{
_applicationName = Constants.CONFIG_AZMAN_APPID;
_application = authorizationStore.OpenApplication(_applicationName, null);
}
catch (System.Runtime.InteropServices.COMException ex)
{
ReleaseCOMObject(authorizationStore);
authorizationStore = null;
throw ex;
}
}
/// <summary>
/// GetApplicationUser
/// Retrieves the permitted operations for the user.
/// </summary>
/// <remarks>
/// Assumes that the application uses Windows Authentication and
/// binds to the user token passed by IIS
/// </remarks>
/// <returns>
/// User object loaded with user properties from AD and allowed operations
/// </returns>
public UserEntity GetApplicationUser ()
{
UserEntity user = new UserEntity();
user.User.AddUserRow (GetUserIdentity().Name, null);
// Get some more Active Directory properties for this user as needed, such as e-mail, full name, etc.
// ....
// retrieve permitted operations for this user from AzMan
GetUserOperations(user);
user.AcceptChanges();
return user;
}
/// <summary>
/// Gets all operations that the current user has permissions to execute.
/// </summary>
/// <remarks>
/// Assumes that the application operations are already loaded in the static constructor
/// </remarks>
/// <returns>
/// HybridDictionary with the operations
/// </returns>
private void GetUserOperations(UserEntity user)
{
HybridDictionary applicationOperations = GetApplicationOperations();
int index = 0;
Debug.Assert (applicationOperations.Count>0);
if (applicationOperations.Count==0) throw new ApplicationException("No operations found.");
// Get the authorized operations
// Need to build an object array of the application operations
// because this is what AzMan API expect
object[] operations = new object[applicationOperations.Count];
foreach (DictionaryEntry o in applicationOperations)
{
operations[index] = ((Operation)o.Value)._id;
index++;
}
try
{
object[] results = GetAuthorizedOperations(operations);
// Add only the authorized operations
for (int i = 0; i < results.Length; i++)
{
Operation appOperation = (Operation)applicationOperations[operations[i]];
if ((int)results[i] == 0) user.Operations.AddOperationsRow(appOperation._id, appOperation._name, appOperation._description);
}
}
catch (System.Runtime.InteropServices.COMException ex)
{
throw new ApplicationException("Exception during AzMan Access Check", ex);
}
}
/// <summary>
/// Checks whether the user is allowed to access a single operation
/// </summary>
/// <remarks>
/// Assumes that the application operations are already loaded in the static constructor
/// </remarks>
/// <param name="operationID">
/// The operation ID to check
/// </param>
/// <returns>
/// true if the user is allowed access, false otherwise
/// </returns>
public static bool IsOperationPermitted (int operationID)
{
// No scopes defined
object [] operation = {operationID};
object[] result = GetAuthorizedOperations(operation);
return (int)result[0]==0?true:false;
}
/// <summary>
/// Determines what access the user has to the passed array of operations.
/// </summary>
/// <remarks>
/// Load the operation IDs in the operation array
/// </remarks>
/// <param name="operations">
/// Array of operations that need to be checked
/// </param>
private static object[] GetAuthorizedOperations (object[] operations)
{
// No scopes defined
object[] scopes = { "" };
IAzClientContext clientContext = null;
try
{
// Get the user context from the token
clientContext = _application.InitializeClientContextFromToken((ulong)GetUserIdentity().Token, null);
object[] results = (object[])clientContext.AccessCheck(
_applicationName,
scopes, operations,
null, null, null, null, null);
return results;
}
catch (System.Runtime.InteropServices.COMException ex)
{
ReleaseCOMObject (clientContext);
throw ex;
}
}
/// <summary>
/// Gets all operations defined in the application store
/// </summary>
/// <returns>
/// Dictionary with all operations
/// </returns>
private HybridDictionary GetApplicationOperations()
{
HybridDictionary operations = null;
// attempt to load the user object from the ASP.NET cache
operations = (HybridDictionary)HttpContext.Current.Cache[Constants.CACHE_OPERATIONS];
if (operations==null)
{
// If not get the all operations for this application
operations = new HybridDictionary();
foreach (IAzOperation op in _application.Operations)
{
operations.Add(op.OperationID, new Operation(op.OperationID, op.Name, op.Description));
}
// cache the operations
double slidingExpiration = Double.Parse(ConfigurationSettings.AppSettings[Constants.CACHE_SLIDING_EXPIRATION]);
HttpContext.Current.Cache.Insert(Constants.CACHE_OPERATIONS, operations, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(slidingExpiration));
}
return operations;
}
/// <summary>
/// A wrapper to release a COM object
/// </summary>
/// <param name="o">
/// COM wrapper to be released
/// </param>
private static void ReleaseCOMObject (object o)
{
if (null != o)
{
while (0 != System.Runtime.InteropServices.Marshal.ReleaseComObject(o))
continue;
}
}
public static WindowsIdentity GetUserIdentity()
{
AppDomain myDomain = Thread.GetDomain();
myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
return (WindowsIdentity)myPrincipal.Identity;
}
}
public struct Operation
{
public Operation(int id, string name, string description)
{
_id = id;
_name = name;
_description = description;
}
public int _id;
public string _name;
public string _description;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -