Fazer uma PerguntaFazer uma Pergunta
 

RespondidoWCF adapter - how to implement authorization?

  • quarta-feira, 16 de janeiro de 2008 14:44Andy Stephens Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    Hi all

     

    If I was writing a "normal" (i.e. non-BizTalk) WCF service I would lock down operations using either the PrincipalPermission attribute or do an IsInRole check in the code, but how would achieve a similar thing with the BizTalk WCF adapter (if it's even possible)?

     

    Thanks in advance

     

    Andy

     

Respostas

  • quarta-feira, 16 de janeiro de 2008 22:15Karahan Celikel - MSFT Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Respondido

    Yes, it is possible.

    You can create your own custom service authorization behavior, and use it with WCF-Custom adapter.

    I'm adding the code block below

     

    1- Compile the code below, and install it to GAC

    2-  Add the following entry to machine.config file

    <system.serviceModel>

        <extensions>

          <behaviorExtensions>

            <add name="myCustomAuth" type="WcfServiceBehaviors.MyCustomBehaviorElement, WcfServiceBehaviors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=PUBLIC KEY OF YOUR DLL" />

          </behaviorExtensions>

        </extensions>

      </system.serviceModel>

     

     

    3- Restart BTS service, and reopen administration console if it's already open.

    4- Create a receive location with WCF-Custom adapter. Choose whatever binding you want. Go to behaviors tab, and add the myCustomAuth binding by right clicking on the serviceBehavior and choosing add extension

     

     

    Code Block

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.ServiceModel;

    using System.ServiceModel.Channels;

    using System.ServiceModel.Description;

    using System.ServiceModel.Configuration;

    using System.IdentityModel.Policy;

    using System.IdentityModel.Claims;

    using System.Security.Principal;

    namespace WcfServiceBehaviors

    {

    public class MyCustomServiceAuthorizationManager : ServiceAuthorizationManager

    {

    protected override bool CheckAccessCore(OperationContext operationContext){

    if (!base.CheckAccessCore(operationContext))

    {

    return false;

    }

    AuthorizationContext authCtx = operationContext.ServiceSecurityContext.AuthorizationContext;

    //you can do your custom authorization here

    //authCtx.ClaimSets

    //authCtx.Properties["Principal"]

    //if you want to do your authorization based on the operation, you can try using operationContext.EndpointDispatcher.ContractName

    return true;

    }

    }

    public class MyCustomBehaviorElement : BehaviorExtensionElement

    {

    protected override object CreateBehavior()

    {

    return new MyCustomServiceBehavior();

    }

    public override Type BehaviorType

    {

    get { return typeof(MyCustomServiceBehavior); }

    }

    }

    public class MyCustomServiceBehavior : IServiceBehavior

    {

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)

    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

    {

    ServiceAuthorizationBehavior authBehavior = serviceDescription.Behaviors.Find<ServiceAuthorizationBehavior>();

    authBehavior.ServiceAuthorizationManager = new MyCustomServiceAuthorizationManager();

    ((IServiceBehavior)authBehavior).ApplyDispatchBehavior(serviceDescription, serviceHostBase);

    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

    {

    }

    #endregion

    }

    }

     

     

     

     

     

     

Todas as Respostas

  • quarta-feira, 16 de janeiro de 2008 22:15Karahan Celikel - MSFT Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     Respondido

    Yes, it is possible.

    You can create your own custom service authorization behavior, and use it with WCF-Custom adapter.

    I'm adding the code block below

     

    1- Compile the code below, and install it to GAC

    2-  Add the following entry to machine.config file

    <system.serviceModel>

        <extensions>

          <behaviorExtensions>

            <add name="myCustomAuth" type="WcfServiceBehaviors.MyCustomBehaviorElement, WcfServiceBehaviors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=PUBLIC KEY OF YOUR DLL" />

          </behaviorExtensions>

        </extensions>

      </system.serviceModel>

     

     

    3- Restart BTS service, and reopen administration console if it's already open.

    4- Create a receive location with WCF-Custom adapter. Choose whatever binding you want. Go to behaviors tab, and add the myCustomAuth binding by right clicking on the serviceBehavior and choosing add extension

     

     

    Code Block

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.ServiceModel;

    using System.ServiceModel.Channels;

    using System.ServiceModel.Description;

    using System.ServiceModel.Configuration;

    using System.IdentityModel.Policy;

    using System.IdentityModel.Claims;

    using System.Security.Principal;

    namespace WcfServiceBehaviors

    {

    public class MyCustomServiceAuthorizationManager : ServiceAuthorizationManager

    {

    protected override bool CheckAccessCore(OperationContext operationContext){

    if (!base.CheckAccessCore(operationContext))

    {

    return false;

    }

    AuthorizationContext authCtx = operationContext.ServiceSecurityContext.AuthorizationContext;

    //you can do your custom authorization here

    //authCtx.ClaimSets

    //authCtx.Properties["Principal"]

    //if you want to do your authorization based on the operation, you can try using operationContext.EndpointDispatcher.ContractName

    return true;

    }

    }

    public class MyCustomBehaviorElement : BehaviorExtensionElement

    {

    protected override object CreateBehavior()

    {

    return new MyCustomServiceBehavior();

    }

    public override Type BehaviorType

    {

    get { return typeof(MyCustomServiceBehavior); }

    }

    }

    public class MyCustomServiceBehavior : IServiceBehavior

    {

    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)

    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

    {

    ServiceAuthorizationBehavior authBehavior = serviceDescription.Behaviors.Find<ServiceAuthorizationBehavior>();

    authBehavior.ServiceAuthorizationManager = new MyCustomServiceAuthorizationManager();

    ((IServiceBehavior)authBehavior).ApplyDispatchBehavior(serviceDescription, serviceHostBase);

    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

    {

    }

    #endregion

    }

    }

     

     

     

     

     

     

  • sexta-feira, 18 de janeiro de 2008 14:05Andy Stephens Medalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuárioMedalhas de usuário
     

    Many thanks for your help.

     

    I was already on the right lines before starting this thread - I had already implemented my own IAuthorizationPolicy (where I create the principal and populate its roles), and had also tried implementing a custom ServiceAuthorizationManager class, but I just couldn't find a way to access the principal object until I saw your code.

     

    Regards

     

    Andy