我有一个每次调用的WCF服务,它在IIS(.svc)中托管.在服务的构造函数中,我根据本文设置了Thread.CurrentPrincipal = HttpContext.Current.User.在这种情况下,HttpContext.Current.User的类型为Microsoft.IdentityModel.Claims.ClaimsPrincipal,并具有从我的自定义被动STS发回的声明.
但是,只要我进入我的服务操作并检查Thread.CurrentPrincipal,当此对象仍然是Microsoft.IdentityModel.Claims.ClaimsIdentity类型时,该对象本身不再与HttpContext.Current.User相同(IsAuthenticated = false) ,AuthenticationType ="",并且Thread.CurrentPrincipal.Identity上的Name为null,而这些值仍然在HttpContext.Current.User上正确填充.这告诉我有些东西拦截了对操作的调用,并错误地将当前主体更改为一些通用的,空的,未经身份验证的声明主体.
我在构造函数和操作中检查了线程ID,并且它在两个地方都是相同的,并且在从HttpContext.Current.User分配后在立即窗口中评估Thread.CurrentPrincipal显示正在正确设置线程标识.构造函数,所以在构造函数和方法之间肯定会执行某些操作,并且有些东西正在改变我的Thread.CurrentPrincipal.
有没有人知道这是做什么的,以及如何防止/解决这种行为?
是否想知道在使用符号和加密令牌的负载平衡环境中部署自定义WCF-安全令牌服务(STS)的最佳实践是什么?
我们正在使用Cirtix NetScaler来处理负载平衡和SSL终止(即证书仅安装在NetScaler服务器上)。已指定STS通过SigningCertificateName和EncryptionCertificateName应用设置对令牌进行签名和加密。但是,当前的Web服务器配置在其证书存储区中未安装本地证书。
所以我的问题是:
我的项目我正在使用WIF (但这对于这个问题的上下文并不重要.你可以使用替代框架处理你的身份验证.问题是在执行ajax请求时处理身份验证失败).然而,在我的情况下,我编写了自定义服务器逻辑,它继承自ClaimsAuthenticationManager并处理身份验证:
public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
{
// add some custom claims
}
return incomingPrincipal;
}
Run Code Online (Sandbox Code Playgroud)
现在,在我删除所有会话Cookie后,再次输入任何页面,我被重定向到WIF服务的登录页面,我被要求再次登录.一切都按预期工作.
但是如果我做了一个ajax请求,我就会收到一个错误,这个错误被拦截了:
$(document).ready(function () {
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
// do something
}
});
});
Run Code Online (Sandbox Code Playgroud)
不幸的是,XMLHttpRequest对象没有返回任何有意义的消息,基于此我可以像其他人一样以任何其他方式处理这种错误.在这种特殊情况下,我只希望应用程序重定向到登录页面 - 正常请求就是这样.

在执行ajax调用时,将调用方法Authenticatefrom ClaimsAuthenticationManager.Identity.IsAuthenticated返回false,方法结束,一切都完成.即使是OnAuthorization方法from BaseController也没有被调用,所以我无法将任何状态传递给ajax结果对象.
protected override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest() && !User.Identity.IsAuthenticated)
{
//do something, …Run Code Online (Sandbox Code Playgroud) 我正在我的.net 4.5应用程序中实现基于声明的安全性.很多篮球跳过,但它基本上工作.
我不喜欢的唯一部分是我无法创建自己的属性.ClaimsPrincipalPermissionAttribute已被密封.为什么?
我总是在我的应用程序中标记,例如:
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "Foo", Operation = "Bar")]
Run Code Online (Sandbox Code Playgroud)
因为我希望我的资源和操作字符串不会拼写错误并且易于重构,所以我创建了类,所以我可以这样做:
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = Resources.Foo, Operation = Operations.Foo.Bar)]
Run Code Online (Sandbox Code Playgroud)
(请注意,由于不同的资源可能具有不同的操作,因此操作本身由资源子类化.)
这一切都很好,花花公子,但每次输入或复制/粘贴都是一个很大的问题.我宁愿做类似的事情:
[DemandPermission(Resources.Foo, Operations.Foo.Bar)]
Run Code Online (Sandbox Code Playgroud)
我可以创建这个属性,但我需要从ClaimsPrincipalPermissionAttribute继承,我不能,因为它是密封的.:(
还有其他方法可以解决这个问题吗?也许我不需要继承,但我能以某种方式注册我自己的属性类型,所以它可以在所有相同的地方工作吗?
我正在尝试使用自定义服务器端登录页面,使用本教程中的代码以及此代码示例,将FederatedAuthentication与.NET 4.5,MVC 4和主动重定向结合在一起.
重定向到我的AccountController的LogOn方法工作正常,方法如下所示:
public ActionResult LogOn()
{
HrdClient hrdClient = new HrdClient();
WSFederationAuthenticationModule fam = FederatedAuthentication.WSFederationAuthenticationModule; /*** Fails here because this is null **/
HrdRequest request = new HrdRequest(fam.Issuer, fam.Realm, context: Request.QueryString["ReturnUrl"]);
IEnumerable<HrdIdentityProvider> hrdIdentityProviders = hrdClient.GetHrdResponse(request);
ViewData["Providers"] = hrdIdentityProviders;
return View();
}
Run Code Online (Sandbox Code Playgroud)
这失败,因为FederatedAuthentication.WSFederationAuthenticationModule是null.
使用VS 2012,我运行了新的Identity and Access向导(它似乎取代了旧的STS对话框).这给了我一个FederationMetadata文件夹,看起来是正确的,并对我的Web.Config进行了一些修改.特别是,模块部分如下所示:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
<add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" />
</modules>
Run Code Online (Sandbox Code Playgroud)
在看过SO答案 …
由Visual Studio 2012中的默认(Internet)模板创建的MVC 4应用程序在运行"身份和访问..."向导后返回RolePrincipal.
该向导与STS(实际或"开发"时间STS)建立信任关系.
如果检查,User对象将是RolePrincipal类型.这样做的结果是User.IsInRole针对本地角色数据库而不是声明集进行解析.

我期待一个ClaimsPrincipal
如果访问通过HTTPS实现为ASP.NET Web API Controller的端点的客户端提供客户端证书,则该证书可通过Request.GetClientCertificate.但是,我想知道:是否有可能以基于声明的模型的形式提供与.NET 4.5中的安全模型集成的信息?
我想这样做的主要原因是我需要不同的客户端才能以不同的方式进行身份验证以访问相同的服务,因此我更愿意从证书等细节中抽象出来.我希望我的控制器能够根据当前用户的索赔做出决策,而不必担心这些索赔的起源.
我知道有一种X509CertificateClaimSet类型,它看起来像是自然流动:
X509CertificateClaimSet某种令牌映射过程表示(类似于您可以用于ACS的联合提供程序生成的传入cookie如何由SessionSecurityTokenHandler ClaimsAuthenticationManager并配置的<claimsAuthenticationManager>元素)检查来自证书的声明集,并将其转换为特定于非令牌的特定于应用程序的声明甚至有一个X509SecurityTokenHandler,听起来应该这样做.但是,据我所知,这是针对在发送的消息中处理基于证书的身份验证的情况而设计的 - 它似乎没有任何支持证书的所有权证明发生在传输级别,即作为TLS/SSL握手的一部分.
我想知道是否需要编写自己的模块来执行此操作.理论上,看起来它可能只是处理AuthenticateRequest事件,查看证书请求,X509CertificateClaimSet如果存在则从证书构建.但是......那又怎样?我只是创建自己的ClaimsPrincipal并替换现有用户吗?或者是否有一些"正确"的方式将我发现的声明添加到集合中?(客户端证书不一定是声明的唯一来源 - 我的应用程序已经在使用与ACS集成的声明.是否有一种标准机制来确保所有可能的声明来源都正确合并?)
它看起来像SessionAuthenticationModule(SAM)是当前提供声明主体的身份模型组件,它只是替换先前在上下文中的那个以及当前线程的用户.但它似乎提供了可扩展性 - 如果覆盖它ValidateSessionToken,则返回ClaimsIdentity构成主体的对象集.所以在理论上,我可以覆盖它并在那时添加任何其他声明.
但我不确定这是不行的方式.据我所知,SAM在ClaimsAuthenticationManager完成其声明转换后执行此操作.或者声称转换错误的模型与这里一起去?
asp.net ssl-certificate claims-based-identity wif asp.net-web-api
我们的旧软件架构使用基于角色的验证.我们现在想要使用基于声明的授权.事实上,即使我们使用角色基础技术,我认为我们总是使用一些建模声明.
最低级别是权限.权限可以是"调用添加用户的用户服务"或简称"UserService.Add".权限可以分配给组.用户可以是组的成员.最后,通过组成员身份,用户可以拥有权限列表.
旧系统使用UserNamePasswordValidator,IAuthorizationPolicy和CodeAccessSecurityAttribute的组合来具有在服务方法之上编写的属性,并且在调用服务方法时,将检查有效性.如果用户没有所需的权限,则拒绝访问.工作得很好.
[CompanyRoleRequired(SecurityAction.Demand, Role = "Common.Connect")]
[CompanyRoleRequired(SecurityAction.Demand, Role = "SomeServiceName.Save")]
public void Save(IEnumerable<Data> data)
{
// code
}
Run Code Online (Sandbox Code Playgroud)
现在我想使用基于声明的授权.保持上面的模型,我会为每个以前的特权创建一个声明,或者可能为每个服务创建一个具有其操作的有效值的声明.例如,我可以添加声明"UserService"而不是"UserService.Add",而具有前一个特权的人将获得值为"Add"的声明.我想为服务开发人员提供相同的访问检查,因此我希望在服务方法之上注释所需的声明.Microsoft已为此提供了ClaimsPrincipalPermissionAttribute.
我没有实现IAuthorizationPolicy,而是实现了ClaimsAuthorizationManager.
问题1)授权管理器被调用两次.一次使用肥皂网址,一次使用我的属性.我google了很多,似乎是设计的.我没有区分电话和只检查我的电话的问题,但也许我没有看到什么.是否有一个选项或一种简单的方法可以不使用URL调用soap调用,只调用属性?
问题2)访问检查提供了检查市政是否有索赔的能力.显然,索赔具有类型/名称和值.我本来希望该属性提供这样的接口.但是,该属性想要了解资源和操作.我需要覆盖的访问检查功能还需要检查资源和操作.这是为什么?我是否需要将资源/操作映射到AuthorizationManager中的声明?如果我没有看到任何需要,是否可以将索引的预期类型和值作为资源和操作放在属性中并在授权管理器中以1:1映射它们?或者如果我这样做,我会错过一些重要的安全功能吗?
正如我在另一个问题中所描述的,我构建了一个Web服务,该服务将使用用户名/密码并基于这些凭据在ADFS2中对用户(移动应用程序)进行身份验证.我的Web服务在ADFS上配置为RP.ADFS发布SAML 2.0令牌.
这是web方法的代码:
public class MobileAuthService : IMobileAuthService
{
private const string adfsBaseAddress = @"https://<my_adfs_hostname>/adfs/services/";
private const string endpointSuffix = @"trust/13/issuedtokenmixedsymmetricbasic256";
public string AuthenticateUser(string username, string password)
{
var binding = new WS2007HttpBinding(SecurityMode.Message);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(adfsBaseAddress + endpointSuffix))
{
TrustVersion = TrustVersion.WSTrust13
};
trustChannelFactory.Credentials.UserName.UserName = username;
trustChannelFactory.Credentials.UserName.Password = password;
var tokenClient = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue, KeyTypes.Symmetric);
var token = …Run Code Online (Sandbox Code Playgroud) 我们希望将ASP.NET MVC应用程序从Azure Cloud Service切换到Azure App Service(Web应用程序).该应用程序当前正在使用WIF作为其身份框架,并且当它在服务器场配置中运行时,我们配置了一个SessionSecurityTokenHandler使用证书加密会话cookie 的自定义(因此,cookie可以由Web场的所有实例解密).
我们可以使用csdef/cscfg文件和与Cloud Service关联的内置Azure证书存储在Cloud Service方案中配置此证书,但Azure App Services没有这样的功能(除非我遗漏了一些内容).
有没有办法在App Service中配置证书?我们是否应该回退到另一种加密会话cookie的机制,例如共享机器密钥?机器密钥不是理想的解决方案,因为它迫使我们将某些配置从源代码控制中移除以避免泄漏密钥.