要扩大拉吉斯拉夫的回答是:
号定制UserNamePasswordValidator不能用作角色提供。 UserNamePasswordValidator在OperationContext中的一个单独的上下文(或线程,或者其他)中运行,您想要混淆它。
你需要做的是实现自定义授权。我发现this page对此很有用。警告:在找到有趣的部分之前,有很多管道工程。
本质上讲,你开始一个ServiceCredentials
派生类,在App.config
注册,具体如下:
<serviceBehaviors>
<behavior name="...">
<serviceAuthorization principalPermissionMode="Custom" />
<serviceCredentials type="MyNamespace.MyServiceCredentials, MyAssembly">
<userNameAuthentication userNamePasswordValidationMode="Custom" />
<serviceCertificate etc. />
</serviceCredentials>
关联与您的服务行为。
覆盖以返回MySecurityTokenManager
,源自ServiceCredentialsSecurityTokenManager
。在此,覆盖CreateSecurityTokenAuthenticator
,返回MySecurityTokenAuthenticator
。这应该来自CustomUserNameSecurityTokenAuthenticator
。在那里,覆盖ValidateUserNamePasswordCore
。调用基类,它将返回授权策略列表。
在该列表中添加一个新的:MyAuthorizationPolicy
,它实现IAuthorizationPolicy
。在这方面,你只是(哈),需要做到以下几点:
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
IList<IIdentity> identities = GetIdentities(evaluationContext);
// Find the GenericIdentity with our user-name in it.
IIdentity currentIdentity = identities.SingleOrDefault(
i => i is GenericIdentity &&
StringComparer.OrdinalIgnoreCase.Equals(i.Name, UserName));
if (currentIdentity == null)
throw new InvalidOperationException("No Identity found");
// Replace the GenericIdentity with a new one.
identities.Remove(currentIdentity);
var newIdentity =
new GenericIdentity(_userName, currentIdentity.AuthenticationType);
identities.Add(newIdentity);
// This makes it available as
// ServiceSecurityContext.Current.PrimaryIdentity later.
evaluationContext.Properties["PrimaryIdentity"] = newIdentity;
// This makes it available as Thread.CurrentPrincipal.
IPrincipal newPrincipal = new GenericPrincipal(newIdentity, _roles);
evaluationContext.Properties["Principal"] = newPrincipal;
return true;
}
private static IList<IIdentity> GetIdentities(
EvaluationContext evaluationContext)
{
object identitiesProperty;
if (!evaluationContext.Properties.TryGetValue(
"Identities", out identitiesProperty))
throw new InvalidOperationException("No Identity found");
var identities = identitiesProperty as IList<IIdentity>;
if (identities == null)
throw new InvalidOperationException("No Identity found");
return identities;
}
然后,已经这样做了很多,你可以用PrincipalPermission
标记您的服务操作:
[PrincipalPermission(SecurityAction.Demand, Role = "Editor")]
罗杰,你管理解决这个问题?我想要做同样的事情。 – 2011-04-15 08:42:26