WCF用户名的身份验证:我可以得到用户名和自定义ServiceAuthorizationManager? [英] WCF UserName Authentication: Can I get the Username in a custom ServiceAuthorizationManager?
问题描述
我有一个使用自定义的 ServiceAuthorizationManager
WCF服务。自定义身份验证管理器已成立处理Windows和Forms身份验证。
I have a WCF service that is using a custom ServiceAuthorizationManager
. The custom auth manager is already set up to handle Windows and Forms authentication.
不过,如果我连接与设置为用户名
身份验证客户端,我似乎无法找到任何地方的用户名。
However, if I connect with a client that is set to UserName
auth, I can't seem to find the username anywhere.
客户端code是这样的:
The client code looks like this:
this.ClientCredentials.UserName.UserName = "user";
this.ClientCredentials.UserName.Password = "pass";
this.Open();
this.MyMethod(); // my actual contract method
this.Close();
然后在服务器上,我有我的自定义身份验证管理器:
Then on the server, I have my custom auth manager:
public sealed class AppAuthorizationManager : ServiceAuthorizationManager
{
public override bool CheckAccess(OperationContext operationContext, ref Message message)
{
// would like to check user/pwd here...
}
}
这可能吗?
Is this possible?
- 的
Thread.CurrentPrincipal中
没有设置, -
operationContext.ServiceSecurityContext.PrimaryIdentity
未设置。 -
operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
是空的。
- The
Thread.CurrentPrincipal
is not set, operationContext.ServiceSecurityContext.PrimaryIdentity
is not set.operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
is empty.
时的用户名/密码应该在任何地方可用?还是我必须添加自定义 UsernamePasswordValidator
吗?
Is the user/pwd supposed to be available anywhere? Or do I have to add a custom UsernamePasswordValidator
too?
更新:所以我增加了一个自定义的 UserNamePasswordValidator
和 IAuthorizationPolicy
。
我的更新WCF的配置是这样的:
Update: So I added a custom UserNamePasswordValidator
and an IAuthorizationPolicy
.
My updated WCF config looks like this:
<behavior name="Server2ServerBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="MyApp.AuthManager, MyApp">
<authorizationPolicies>
<add policyType="MyApp.TokenAuthorizationPolicy, MyApp" />
</authorizationPolicies>
</serviceAuthorization>
<serviceCredentials>
<userNameAuthentication customUserNamePasswordValidatorType="MyApp.PFUserNameValidator, MyApp" />
</serviceCredentials>
</behavior>
如果我把所有3这些类的断点,WCF抛出异常:
If I set a breakpoint in all 3 of those classes, WCF throws the exception:
LogonUser failed for the 'username' user. Ensure that the user has a valid Windows account.
at System.IdentityModel.Selectors.WindowsUserNameSecurityTokenAuthenticator.ValidateUserNamePasswordCore(String userName, String password)
在其中任何一个都运行。嗯...
Before any of them are run. Hmmm...
推荐答案
这是在的 UsernamePasswordValidator - 这是你将有机会获得密码的唯一的地方。然而,这是不是你设置的委托 - 这将是在 IAuthorizationPolicy
的评估
方法,该方法看起来是这样的:
This is normally handled in the UsernamePasswordValidator - which is the only place you'll have access to the password. However, this isn't where you set the principal - that would be in the IAuthorizationPolicy
's Evaluate
method, which might look something like:
bool IAuthorizationPolicy.Evaluate(
EvaluationContext evaluationContext, ref object state)
{
IList<IIdentity> idents;
object identsObject;
if (evaluationContext.Properties.TryGetValue(
"Identities", out identsObject) && (idents =
identsObject as IList<IIdentity>) != null)
{
foreach (IIdentity ident in idents)
{
if (ident.IsAuthenticated &&
ident.AuthenticationType == TrustedAuthType)
{
evaluationContext.Properties["Principal"]
= //TODO our principal
return true;
}
}
}
if (!evaluationContext.Properties.ContainsKey("Principal"))
{
evaluationContext.Properties["Principal"] = //TODO anon
}
return false;
}
(其中 TrustedAuthType
是我们的密码验证程序的名称)
(where TrustedAuthType
is the name of our password validator)
有了这个地方,线程的校长将被设置,我们可以找出我们自己(和使用基于角色的安全性等)
With this in place, the thread's principal will be set, and we can identify ourselves (and use roles-based security etc)
这篇关于WCF用户名的身份验证:我可以得到用户名和自定义ServiceAuthorizationManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!