要擴大拉吉斯拉夫的回答是:
號定製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