To expand Ladislav's answer:
. UserNamePasswordValidator . UserNamePasswordValidator ( - ) OperationContext, .
. , . : , .
, ServiceCredentials -derived, App.config, :
<serviceBehaviors>
<behavior name="...">
<serviceAuthorization principalPermissionMode="Custom" />
<serviceCredentials type="MyNamespace.MyServiceCredentials, MyAssembly">
<userNameAuthentication userNamePasswordValidationMode="Custom" />
<serviceCertificate etc. />
</serviceCredentials>
.
ServiceCredentials.CreateSecurityTokenManager, MySecurityTokenManager, ServiceCredentialsSecurityTokenManager. CreateSecurityTokenAuthenticator, a MySecurityTokenAuthenticator. CustomUserNameSecurityTokenAuthenticator. ValidateUserNamePasswordCore. , .
: MyAuthorizationPolicy, IAuthorizationPolicy. (hah) :
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
IList<IIdentity> identities = GetIdentities(evaluationContext);
IIdentity currentIdentity = identities.SingleOrDefault(
i => i is GenericIdentity &&
StringComparer.OrdinalIgnoreCase.Equals(i.Name, UserName));
if (currentIdentity == null)
throw new InvalidOperationException("No Identity found");
identities.Remove(currentIdentity);
var newIdentity =
new GenericIdentity(_userName, currentIdentity.AuthenticationType);
identities.Add(newIdentity);
evaluationContext.Properties["PrimaryIdentity"] = newIdentity;
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")]