CustomAuthorizationPolicy.EEvaluate()方法从不在wcf-webhttpbinding



我创建了一个wcf服务,如您所见:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
[WebInvoke(Method = "GET", UriTemplate = "/Data/{data}")]
string GetData(string data);

因此,我创建了一个自定义授权,如您所见:

public class AuthorizationPolicy : IAuthorizationPolicy
{
string id = Guid.NewGuid().ToString();
public string Id
{
get { return this.id; }
}
public System.IdentityModel.Claims.ClaimSet Issuer
{
get { return System.IdentityModel.Claims.ClaimSet.System; }
}
// this method gets called after the authentication stage
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
// get the authenticated client identity
IIdentity client = HttpContext.Current.User.Identity;
// set the custom principal
evaluationContext.Properties["Principal"] = new CustomPrincipal(client);
return true;
}
}
public class CustomPrincipal : IPrincipal
{
private IIdentity _identity;
public IIdentity Identity
{
get
{
return _identity;
}
}
public CustomPrincipal(IIdentity identity)
{
_identity = identity;
}
public bool IsInRole(string role)
{
//my code 
return true;
// return Roles.IsUserInRole(role);
}
}

和身份验证:

public class RestAuthorizationManager: ServiceAuthorizationManager
{
protected override bool CheckAccessCore(OperationContext operationContext)
{
//Extract the Authorization header, and parse out the credentials converting the Base64 string:  
var authHeader = WebOperationContext.Current.IncomingRequest.Headers["Authorization"];
if ((authHeader != null) && (authHeader != string.Empty))
{
var svcCredentials = System.Text.ASCIIEncoding.ASCII
.GetString(Convert.FromBase64String(authHeader.Substring(6)))
.Split(':');
var user = new
{
Name = svcCredentials[0],
Password = svcCredentials[1]
};
if ((user.Name == "1" && user.Password == "1"))
{
//here i get the role of my user from the database
// return Admin role 
//User is authrized and originating call will proceed  
return true;
}
else
{
//not authorized  
return false;
}
}
else
{
//No authorization header was provided, so challenge the client to provide before proceeding:  
WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate: Basic realm="MyWCFService"");
//Throw an exception with the associated HTTP status code equivalent to HTTP status 401  
throw new WebFaultException(HttpStatusCode.Unauthorized);
}
}
}

所以我在IIS中创建并https托管,然后上传服务,我的身份验证类正在工作,但我的授权没有。为什么?如您所见,我在web配置中定义了身份验证。但我不知道如何在我的网络配置中定义我的授权。

<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<client />
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization
serviceAuthorizationManagerType  
="wcfrestauth.RestAuthorizationManager, wcfrestauth"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpServiceBehavior">
<!-- Important this is the behavior that makes a normal WCF service to REST based service-->
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="wcfrestauth.Service1" behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost/WCFRestAuthentication/api/" />
</baseAddresses>
</host>
<endpoint binding="webHttpBinding" contract="wcfrestauth.IService1" behaviorConfiguration="webHttpServiceBehavior" />
</service>
</services>
<protocolMapping>
<add binding="webHttpBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

我的意思是,当我在客户端调用我的服务时,该服务不检查authorize函数。我应该在webconfig中定义我的自定义authorize类,但我不知道如何定义?

public bool IsInRole(string role)
{
//my code 
return true;
// return Roles.IsUserInRole(role);
}

您可能需要在web config文件中设置serviceCredentials

<serviceCredentials type="YourString">
<YourTagsHere>
</YourTagsHere>
</serviceCredentials>

以下是有关serviceCredentials的更多信息的链接:https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicecredentials

您可以在<serviceAuthorization>标签中指定自定义AuthorizationPolicy,例如:

<serviceAuthorization serviceAuthorizationManagerType=
"wcfrestauth.RestAuthorizationManager, wcfrestauth">
<authorizationPolicies>         
<add policyType="wcfrestauth.AuthorizationPolicy, wcfrestauth"  
</authorizationPolicies> 
</serviceAuthorization>

在WCF文档中,有一个为WCF服务实现自定义授权策略的好例子。

不过,在重写抽象AuthorizationManager基类的CheckAccess方法时要小心。基类的方法在内部调用GetAuthorizationPolicies方法,以检索存在的所有IAuthorizationPolicy对象的集合(另请参阅这篇博客文章-编辑:链接已失效,但文章在Internet档案中)。

如果覆盖CheckAcces并且不调用父类的方法,则不会调用IAuthorizationPolicy对象的任何Evaluate方法。

最新更新