Метод CustomAuthorizationPolicy.Evaluate() никогда не запускается в 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);
}
}
}
Итак, я создаю и https-хостинг в своем IIS, и я загружаю эту услугу, мой класс проверки подлинности работает, но моя авторизация не работает. Почему? Я определяю свою аутентификацию в своей веб-конфигурации, как вы можете видеть. Но я не знаете, как я могу определить свою авторизацию в моей веб-конфигурации.
<?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>
Я имею в виду, когда я вызываю свое обслуживание в клиенте. Служба не проверяет функцию авторизации. я должен определить мой собственный класс полномочий в webconfig, но я не знаю, как это сделать?
public bool IsInRole(string role)
{
//my code
return true;
// return Roles.IsUserInRole(role);
}
Ответы
Ответ 1
Вам может потребоваться установить serviceCredentials
в ваш файл web config
:
<serviceCredentials type="YourString">
<YourTagsHere>
</YourTagsHere>
</serviceCredentials>
Здесь ссылка на дополнительную информацию о serviceCredentials
: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/servicecredentials
Ответ 2
Вы можете указать свою пользовательскую AuthorizationPolicy в тегах <serviceAuthorization>
, например:
<serviceAuthorization serviceAuthorizationManagerType=
"wcfrestauth.RestAuthorizationManager, wcfrestauth">
<authorizationPolicies>
<add policyType="wcfrestauth.AuthorizationPolicy, wcfrestauth"
</authorizationPolicies>
</serviceAuthorization>
В документах WCF есть хороший пример для реализации Custom Authorization Policy для службы WCF.
Будьте осторожны, если переопределить метод CheckAccess абстрактного базового класса AuthorizationManager. Метод базового класса внутренне вызывает метод GetAuthorizationPolicies
для извлечения коллекции всех объектов IAuthorizationPolicy (см. Также в этой статье в блоге).
Если вы переопределите CheckAcces и не вызываете метод родительского класса, не будет вызван какой-либо метод Evaluate объектов IAuthorizationPolicy.