У нас очень похожая настройка, где я работаю.Как отметил @Mystere Man, с этой настройкой есть риски, но если вся инфраструктура настроена и работает правильно, мы обнаружили, что это безопасная установка (мы делаем заботимся о безопасности).Необходимо убедиться в том, что агент SiteMinder работает на узле IIS, который вы пытаетесь защитить, поскольку он проверяет зашифрованный ключ SMSESSION, также переданный в заголовках, что сделает запросы безопасными (это будет чрезвычайно сложноподделать значение заголовка SMSESSION).
Мы используем ASP.NET MVC3, который имеет фильтры глобальных действий, что мы и используем.Но с MVC2 вы можете создать обычный фильтр действий на уровне контроллера, который можно применить к базовому классу контроллера, чтобы обеспечить защиту всех ваших контроллеров / действий.
Мы создали специальный раздел конфигурации, который позволяетнам включить и отключить этот фильтр безопасности через web.config.Если он отключен, в нашем разделе конфигурации есть свойства, которые позволят вам «выдавать себя» за данного пользователя с заданными ролями для целей тестирования и отладки.Этот раздел конфигурации также позволяет нам хранить значения ключей заголовка, которые мы ищем, также в config, на случай, если поставщик когда-либо изменит имена ключей заголовка на нас.
public class SiteMinderConfiguration : ConfigurationSection
{
[ConfigurationProperty("enabled", IsRequired = true)]
public bool Enabled
{
get { return (bool)this["enabled"]; }
set { this["enabled"] = value; }
}
[ConfigurationProperty("redirectTo", IsRequired = true)]
public RedirectToElement RedirectTo
{
get { return (RedirectToElement)this["redirectTo"]; }
set { this["redirectTo"] = value; }
}
[ConfigurationProperty("sessionCookieName", IsRequired = true)]
public SiteMinderSessionCookieNameElement SessionCookieName
{
get { return (SiteMinderSessionCookieNameElement)this["sessionCookieName"]; }
set { this["sessionCookieName"] = value; }
}
[ConfigurationProperty("userKey", IsRequired = true)]
public UserKeyElement UserKey
{
get { return (UserKeyElement)this["userKey"]; }
set { this["userKey"] = value; }
}
[ConfigurationProperty("rolesKey", IsRequired = true)]
public RolesKeyElement RolesKey
{
get { return (RolesKeyElement)this["rolesKey"]; }
set { this["rolesKey"] = value; }
}
[ConfigurationProperty("firstNameKey", IsRequired = true)]
public FirstNameKeyElement FirstNameKey
{
get { return (FirstNameKeyElement)this["firstNameKey"]; }
set { this["firstNameKey"] = value; }
}
[ConfigurationProperty("lastNameKey", IsRequired = true)]
public LastNameKeyElement LastNameKey
{
get { return (LastNameKeyElement)this["lastNameKey"]; }
set { this["lastNameKey"] = value; }
}
[ConfigurationProperty("impersonate", IsRequired = false)]
public ImpersonateElement Impersonate
{
get { return (ImpersonateElement)this["impersonate"]; }
set { this["impersonate"] = value; }
}
}
public class SiteMinderSessionCookieNameElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class RedirectToElement : ConfigurationElement
{
[ConfigurationProperty("loginUrl", IsRequired = false)]
public string LoginUrl
{
get { return (string)this["loginUrl"]; }
set { this["loginUrl"] = value; }
}
}
public class UserKeyElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class RolesKeyElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class FirstNameKeyElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class LastNameKeyElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class ImpersonateElement : ConfigurationElement
{
[ConfigurationProperty("username", IsRequired = false)]
public UsernameElement Username
{
get { return (UsernameElement)this["username"]; }
set { this["username"] = value; }
}
[ConfigurationProperty("roles", IsRequired = false)]
public RolesElement Roles
{
get { return (RolesElement)this["roles"]; }
set { this["roles"] = value; }
}
}
public class UsernameElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
public class RolesElement : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public string Value
{
get { return (string)this["value"]; }
set { this["value"] = value; }
}
}
Итак, наша сеть.конфиг выглядит примерно так
<configuration>
<configSections>
<section name="siteMinderSecurity" type="MyApp.Web.Security.SiteMinderConfiguration, MyApp.Web" />
...
</configSections>
...
<siteMinderSecurity enabled="false">
<redirectTo loginUrl="https://example.com/login/?ReturnURL={0}"/>
<sessionCookieName value="SMSESSION"/>
<userKey value="SM_USER"/>
<rolesKey value="SN-AD-GROUPS"/>
<firstNameKey value="SN-AD-FIRST-NAME"/>
<lastNameKey value="SN-AD-LAST-NAME"/>
<impersonate>
<username value="ImpersonateMe" />
<roles value="Role1, Role2, Role3" />
</impersonate>
</siteMinderSecurity>
...
</configuration>
У нас есть собственный SiteMinderIdentity ...
public class SiteMinderIdentity : GenericIdentity, IIdentity
{
public SiteMinderIdentity(string name, string type) : base(name, type) { }
public IList<string> Roles { get; set; }
}
И собственный SiteMinderPrincipal ...
public class SiteMinderPrincipal : GenericPrincipal, IPrincipal
{
public SiteMinderPrincipal(IIdentity identity) : base(identity, null) { }
public SiteMinderPrincipal(IIdentity identity, string[] roles) : base(identity, roles) { }
}
И мы заполняемHttpContext.Current.User
и Thread.CurrentPrincipal
с экземпляром SiteMinderPrincipal
, который мы создаем на основе информации, которую мы извлекаем из заголовков запросов в нашем фильтре действий ...
public class SiteMinderSecurity : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response;
if (MyApp.SiteMinderConfig.Enabled)
{
string[] userRoles = null; // default to null
userRoles = Array.ConvertAll(request.Headers[MyApp.SiteMinderConfig.RolesKey.Value].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), r => r.Trim());
var identity = new SiteMinderIdentity(request.Headers[MyApp.SiteMinderConfig.UserKey.Value];, "SiteMinder");
if (userRoles != null)
identity.Roles = userRoles.ToList();
var principal = new SiteMinderPrincipal(identity, userRoles);
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;
}
else
{
var roles = Array.ConvertAll(MyApp.SiteMinderConfig.Impersonate.Roles.Value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), r => r.Trim());
var identity = new SiteMinderIdentity(MyApp.SiteMinderConfig.Impersonate.Username.Value, "SiteMinder") { Roles = roles.ToList() };
var principal = new SiteMinderPrincipal(identity, roles);
HttpContext.Current.User = principal;
Thread.CurrentPrincipal = principal;
}
}
}
MyApp
является статическимкласс, который инициализируется при запуске приложения, который кэширует информацию о конфигурации, поэтому мы не читаем ее из web.config при каждом запросе ...
public static class MyApp
{
private static bool _isInitialized;
private static object _lock;
static MyApp()
{
_lock = new object();
}
private static void Initialize()
{
if (!_isInitialized)
{
lock (_lock)
{
if (!_isInitialized)
{
// Initialize application version number
_version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
_siteMinderConfig = (SiteMinderConfiguration)ConfigurationManager.GetSection("siteMinderSecurity");
_isInitialized = true;
}
}
}
}
private static string _version;
public static string Version
{
get
{
Initialize();
return _version;
}
}
private static SiteMinderConfiguration _siteMinderConfig;
public static SiteMinderConfiguration SiteMinderConfig
{
get
{
Initialize();
return _siteMinderConfig;
}
}
}
Из того, что я понял из вашей ситуации, у вас есть информация вбаза данных, которую вам нужно искать, основываясь на информации в заголовках, чтобы получить все, что вам нужно, так что это будет не совсем то, что вам нужно, но, похоже, это должно, по крайней мере, заставить вас
Надеюсь, это поможет.