我有一个使用WIF进行身份验证的wcf webservice.此Web服务的部分职责是生成报告并通过电子邮件发送.如果我使用数据呈现报告,一切都很好.如果我包含任何报表参数,报表常量,甚至只包含DateTime.现在我得到以下异常:
An error occurred during local report processing.Failed to load expression host assembly. Details: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed
Run Code Online (Sandbox Code Playgroud)
我可以在不使用WIF的WCF服务中运行相同的报告,因此很明显有关安全环境的内容已经过时了.
我真的不知道如何解决这个问题.有人可以帮忙吗?谢谢!
错误:
ID4175:IssuerNameRegistry无法识别安全令牌的颁发者.要从此颁发者接受安全性令牌,请配置IssuerNameRegistry以返回此颁发者的有效名称.
情况:我在一台IIS服务器(我的QA环境)上运行了3或4个asp.net应用程序,今天早上开始返回此错误.我从一个匿名站点开始,单击指向安全部分的链接,重定向到我的联合服务代理,进行身份验证,然后重定向回我的安全页面,但会出现此错误.
这个链接和其他一些链接表明我的web.config中的指纹是错误的,但我可以证明(通过TFS中的历史记录)我的web.config文件中的指纹没有改变.
我已经尝试重新运行fedutil,但仍然得到相同的消息(尽管它提供了不同的指纹).有任何想法吗?
使用.Net 4.5 RC和Azure访问控制服务,我感兴趣的主要声明是IdentityProvider和NameIdentifier.
System.Security.Claims.ClaimTypes包含众所周知的声明的常量,它有ClaimTypes.NameIdentifier,但似乎缺少ClaimTypes.IdentityProvider.
我真的很惊讶没有在那里找到它.当然,我可以在我自己的一个常量中使用字符串表示"http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",但鉴于微软对云的推动,我希望使用标准的ClaimTypes找到它.
这只是疏忽吗?有没有充分的理由让它缺席?它在其他名称空间中吗?
我在单个生产环境中遇到了一个非常棘手的问题.
你有两个用户,A和B.用户A登录,一切正常.用户B登录,用户B登录后,用户A现在拥有与用户B相同的安全令牌.
我们的WIF设置是相当标准的,我们在令牌上注入了一些自定义声明,但其他所有内容看起来都是标准的,就令牌的创建和存储方式而言(由WIF处理).
感觉我可能遇到了一些我不熟悉的WIF的奇怪边缘情况
更新:A和B都可以位于不同的计算机上,也可以位于同一台计算机上的不同浏览器中.
我们在请求服务时获取令牌的位置
if (HttpContext.Current == null)
return null;
if (HttpContext.Current.Cache == null)
return null;
if (FederatedAuthentication.SessionAuthenticationModule == null)
return null;
if (FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken == null)
return null;
var sessionToken = FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken;
if (sessionToken.ClaimsPrincipal == null)
throw new InvalidOperationException("The ClaimsPrincipal property of the FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken object is null");
if (sessionToken.ClaimsPrincipal.Identities == null)
throw new InvalidOperationException("The ClaimsPrincipal.Identities sub-property of the FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken object is null");
if (sessionToken.ClaimsPrincipal.Identities.Count == 0)
throw new InvalidOperationException("The ClaimsPrincipal.Identities sub-property of the FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken object has no identities"); …Run Code Online (Sandbox Code Playgroud) 在MVC中这两个有什么区别?
它们看起来完全相同,它们甚至返回相同的类型/类别,System.Web.Security.RolePrincipal但有细微之处.
例如.当针对通过ClaimsPrincipal.Current生成的实例调用时,以下代码会引发各种错误
cp.FindFirst(ClaimTypes.Name); //{"Unable to connect to SQL Server database."} <--HUH!?
cp.Claims; //{"Value cannot be null.\r\nParameter name: username"}
Run Code Online (Sandbox Code Playgroud)
当cp是这样时,上面的工作:
var cp = System.Web.HttpContext.Current.User
Run Code Online (Sandbox Code Playgroud)
通过快速查看向私人成员钻取时,我可以看到他们都有相同的声明字典.但无论出于何种原因,公共财产在被召回的对象被召唤时都会受到打击ClaimsPrincipal.Current
帮助 - 这是为什么!?这真让我抓狂.
=============编辑==================
一定是上床睡觉的时候了.
IPrincipal支持多种身份.它需要某种商店.IIdentity返回ClaimsIdentity的实例,不需要商店.
我只是钻错了属性.他们两个的形状几乎相同,即.相同的属性和方法,我让他们感到困惑.
model-view-controller asp.net-mvc claims-based-identity wif azure-acs
我正在使用Asp.Net 5 MVC,Owin和Oauth2 bearer token作为auth类型开发一个Web应用程序.
按照本指南将Json序列化的自定义复杂声明添加到Microsoft.IdentityModel.Claims.ClaimsIdentity成功的实例中,我尝试使用命名空间上的ClaimsIdentity复制相同的示例System.Security.Claims.
不幸的是,似乎complexClaim在ClaimsIdentity实例中添加了一个派生类类型信息,并将声明存储为System.Security.Claims.Claim.
var complexClaim = new ComplexClaim<UKPassport>(@"http://it.test/currentpassport", passport);
var claims = new List<Claim>() { complexClaim };
identity.AddClaims(claims);
Run Code Online (Sandbox Code Playgroud)
当我尝试从身份中获取声明时,将其转换为ComplexClaim<UKPassport>Type会导致null值.
var passportClaim = identity.Claims.FirstOrDefault<Claim>(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim<UKPassport>;
Run Code Online (Sandbox Code Playgroud)
相同的例子完美地使用Microsoft.IdentityModel.Claims.
任何提示?
这是完整的移植代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Security.Claims;
namespace ConsoleApplication1
{
class Program {
private static ClaimsIdentity identity = new ClaimsIdentity();
static …Run Code Online (Sandbox Code Playgroud) 没解决 - 仍在寻找解决方案.
我正在通过SAML令牌传入WCF调用:
private static string serviceEndpoint = "https service endpoint";
public static void CallProviderService(SecurityToken token)
{
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
var channelFactory = new ChannelFactory<ISomeProviderService>(binding, new EndpointAddress(new Uri(serviceEndpoint)));
string thumb = "mycertthumbprint";
channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindByThumbprint, thumb);
channelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerOrChainTrust;
channelFactory.ConfigureChannelFactory();
channelFactory.Credentials.SupportInteractive = false;
var elements = service.Endpoint.Binding.CreateBindingElements();
elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
service.Endpoint.Binding = new CustomBinding(elements);
var channel = channelFactory.CreateChannelWithIssuedToken<ISomeProviderService>(token);
try
{
var response = channel.MyServiceMethod(somedataobject);
}
catch (Exception ex)
{
//log …Run Code Online (Sandbox Code Playgroud) 在WIF之前,Application_PostAcquireRequestState是创建自定义标识的好地方,但需要大量框架来确保您正在进行的每种类型的身份验证都已正确映射.通过自定义标识,我的意思是继承自Identity的类,例如下面的SomeIdentity,这样我们就可以拥有一个特定的属性,我们可能需要所有经过身份验证的用户拥有.
PostAcquirerequestState仍然可用,但是有很多新方法可以挂钩进行身份验证.此外,支持多种身份验证方法时,旧方法变得复杂.
我想知道在WIF中是否有比下面更好的方法来实现这一点.主要是我想将处理映射声明的代码分离出来.这个想法是代码对于其他身份验证类型/提供者而言是不同的,因为它检索该属性值的方式可能不是来自诸如SAML的声明,而是来自其他地方的其他类型的身份验证方法.我Kentor.AuthServices目前正在使用SAML支持.虽然可能有不同的代码用于根据提供程序映射这些值,但最终结果是已创建SomeIdentity实例并且将设置SomeProperty和其他属性.这样,应用程序的其余部分总是可以依赖/假设已经处理过.
我的MVC项目想出了一个AccountController即有ExternalLoginCallback其隐含的可能是,当外部认证结束一个良好的钩的名字(这对我SAML是"外部"认证).但是,在SAML身份验证期间/之后的任何时候似乎都没有受到攻击.
可能答案是我们仍然需要以旧方式将它们拼凑在一起,但我希望WIF有一些更好的框架钩子来使这更容易.
public sealed class SomeIdentity : Identity
{
...
// Some custom properties
public string SomeProperty { get;set;}
}
protected void Application_PostAcquireRequestState(object sender, EventArgs e)
{
...
identity = new SomeIdentity(id, userId);
// map a claim to a specific property
identity.SomeProperty = ...Claims[IdpSomePropertyKey];
///...
GenericPrincipal newPrincipal = new GenericPrincipal(identity , null);
HttpContext.Current.User = newPrincipal;
System.Threading.Thread.CurrentPrincipal = newPrincipal;
}
Run Code Online (Sandbox Code Playgroud)
现在我正在使用WIF,我应该在哪里放置特定于特定身份验证类型的代码(即Kentor.AuthServices SAML)来创建自定义SomeIdentity?
我的想法是,SomeIdentity将是我的应用程序中随处使用的标识类,但是填充它的属性的代码将需要专门针对每种身份验证类型编写,例如使用SAML来提取声明并使用它们的值来设置proeprties.即它是映射发生的地方.
我使用ADFS 2.0已经有一段时间了,我理解它是如何工作的.我已经完成了十几个自定义RP,自定义STS以及使用ADFS作为依赖STS.
但是,我有一个简单的要求,我仍然无法实现.
我希望我的用户在一段固定的时间后被迫重新登录.我们说1分钟,用于测试目的.
首先,我在RP方面进行了一些修正.似乎由于未知原因,即使令牌的validTo时间点回到原点,RP也会保留会话.这与Vittorio Bertocci在他的书(第123页)中所说的相反,他在书中展示了如何执行滑动过期 - 他说"SessionAuthenticationModule将负责处理过期的会话".好吧,对我来说它没有,但是我在这里找到了一个技巧http://blogs.planbsoftware.co.nz/?p=521 - 看看"if"条款:
sam.SessionSecurityTokenReceived +=
( s, e ) =>
{
SessionAuthenticationModule _sam = s as SessionAuthenticationModule;
DateTime now = DateTime.UtcNow;
DateTime validFrom = e.SessionToken.ValidFrom;
DateTime validTo = e.SessionToken.ValidTo;
try
{
double halfSpan = ( validTo - validFrom ).TotalSeconds / 2;
if ( validTo < now )
{
_sam.DeleteSessionTokenCookie();
e.Cancel = true;
}
}
catch ( Exception ex )
{
int v = 0;
}
};
Run Code Online (Sandbox Code Playgroud)
这个技巧解决了RP方面的问题.当令牌无效时,应用程序将其清除并重定向到登录页面.
现在出现了问题.我的登录页面使用该 …
我有一个WCF服务,它的Thread.CurrentPrincipal设置在ServiceConfiguration.ClaimsAuthorizationManager.
当我像这样异步实现服务时:
public IAsyncResult BeginMethod1(AsyncCallback callback, object state)
{
// Audit log call (uses Thread.CurrentPrincipal)
var task = Task<int>.Factory.StartNew(this.WorkerFunction, state);
return task.ContinueWith(res => callback(task));
}
public string EndMethod1(IAsyncResult ar)
{
// Audit log result (uses Thread.CurrentPrincipal)
return ar.AsyncState as string;
}
private int WorkerFunction(object state)
{
// perform work
}
Run Code Online (Sandbox Code Playgroud)
我发现Thread.CurrentPrincipal在Begin-method和WorkerFunction中设置为正确的ClaimsPrincipal,但是在End-method中它被设置为GenericPrincipal.
我知道我可以为服务启用ASP.NET兼容性并使用HttpContext.Current.User在所有方法中具有正确主体的服务,但我宁愿不这样做.
有没有办法强制Thread.CurrentPrincipal到正确的ClaimsPrincipal而不打开ASP.NET兼容性?
wif ×10
c# ×4
wcf ×3
adfs2.0 ×2
.net ×1
.net-4.5 ×1
acs ×1
asp.net-mvc ×1
async-await ×1
azure-acs ×1
iprincipal ×1
owin ×1
reporting ×1
service ×1