WCF 自定义授权

服务端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.IdentityModel.Claims;
using System.IdentityModel.Policy;
using System.IdentityModel.Selectors;

namespace Services
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string Select();
        [OperationContract]
        string Add();
        [OperationContract]
        string Delete();
    }

    class Service:IService
    {

        public string Select()
        {
            return "Select 被调用";
        }

        public string Add()
        {
            return "Add 被调用";
        }

        public string Delete()
        {
            return "Delete 被调用";
        }
    }

    public class CustomServiceAuthorizationManager : ServiceAuthorizationManager
    {
        protected override bool CheckAccessCore(OperationContext operationContext)
        {
            string action = operationContext.RequestContext.RequestMessage.Headers.Action;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("----------------------------");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("请求的资源,URI:{0}", action);
            //ClaimSet 表示与某个实体关联的声明的集合。
            //获取与授权策略关联的声明集
            foreach (ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
            {
                if (cs.Issuer == ClaimSet.System)
                {
                    foreach (Claim claim in cs.FindClaims("http://tempuri.org/", Rights.PossessProperty))
                    {
                        Console.WriteLine("服务器声明检查,URI:{0}",action);
                        if (claim.Resource.ToString() == action)
                        {
                            Console.WriteLine("通过,URI:{0}",action);
                            return true;
                        }
                    }
                }
            }
            Console.WriteLine("不通过,URI:{0}",action);
            return false;
        }
    }

    public class MyCustomUserNameValidator : UserNamePasswordValidator
    {
        public override void Validate(string userName, string password)
        {
            if (userName == null || password == null)
            {
                throw new ArgumentNullException("用户名或密码不能为空");
            }
            if (userName != "admin" && userName != "admin2")
            {
                throw new Exception("该用户不存在");
            }
        }
    }

    //定义一组用于对用户进行授权的规则。
    public class CustomAuthorizationPolicy : IAuthorizationPolicy
    {
        string id = string.Empty;
        public CustomAuthorizationPolicy()
        {
            id = new Guid().ToString();
        }

        public bool Evaluate(EvaluationContext evaluationContext, ref object state)
        {
            bool flag = false;
            bool r_state = false;
            if (state == null) { state = r_state; } else { r_state = Convert.ToBoolean(state); }

            if (!r_state)
            {
                List<Claim> claims = new List<Claim>();
                foreach (ClaimSet cs in evaluationContext.ClaimSets)
                {
                    foreach (Claim claim in cs.FindClaims(ClaimTypes.Name, Rights.PossessProperty))
                    {
                        Console.WriteLine("用户 : {0}", claim.Resource);
                        foreach (string str in GetOperationList(claim.Resource.ToString()))
                        {
                            claims.Add(new Claim("http://tempuri.org/", str, Rights.PossessProperty));
                            Console.WriteLine("授权的资源:{0}", str);
                        }
                    }
                }
                evaluationContext.AddClaimSet(this, new DefaultClaimSet(Issuer, claims)); r_state = true; flag = true;
            }
            else { flag = true; }
            return flag;
        }

        private static IEnumerable<string> GetOperationList(string username)
        {
            List<string> lists = new List<string>();
            if (username == "admin")
            {
                lists.Add("http://tempuri.org/IService/Select");
                lists.Add("http://tempuri.org/IService/Add");
                lists.Add("http://tempuri.org/IService/Delete");
            }

            else if (username == "admin2")
            {
                lists.Add("http://tempuri.org/IService/Select");
            }
            return lists;
        }

        public ClaimSet Issuer
        {
            get { return ClaimSet.System; }
        }

        public string Id
        {
            get { return id; }
        }
    }
}

服务端配置代码:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Services.Service" behaviorConfiguration="httpBehavior">
        <endpoint address="" binding="wsHttpBinding" contract="Services.IService" bindingConfiguration="wsBinding"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:9001/"/>
          </baseAddresses>
        </host>
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="wsBinding">
          <security mode ="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <behaviors>
      <serviceBehaviors>
        <behavior name="httpBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="WCFServerPK" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
            <userNameAuthentication customUserNamePasswordValidatorType="Services.MyCustomUserNameValidator,Services" userNamePasswordValidationMode="Custom"/>
          </serviceCredentials>

          <serviceAuthorization serviceAuthorizationManagerType="Services.CustomServiceAuthorizationManager,Services">
            <authorizationPolicies>
              <add policyType="Services.CustomAuthorizationPolicy,Services"/>
            </authorizationPolicies>
          </serviceAuthorization>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

--------------------------------------------------------------------------------------------------------------------------------------------------------

客户端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Clients
{
    class Program
    {
        static void Main(string[] args)
        {
            localhost.ServiceClient proxy = new Clients.localhost.ServiceClient();
            proxy.ClientCredentials.UserName.UserName = "admin";
            proxy.ClientCredentials.UserName.Password = "123456789";
            string result = proxy.Add();
            Console.WriteLine(result);
            Console.ReadKey();
        }
    }
}
原文地址:https://www.cnblogs.com/wangshuai/p/1759520.html