• WCF:REST + Basic authentification + IIS


    近期一个项目中用到Restful WCF提供服务,但是需要验证机制,网上搜刮了一些,都是太复杂。翻墙找到了一篇不错的文章分享一下。

    原地址连接:http://vgolovchenko.wordpress.com/2012/05/20/wcf-soaprest-ssl-basic-authentification-iis/

    如何实现REST + Basic auth?

    1. 创建WCF lib宿主到iis上

    参考:http://www.cnblogs.com/yongqiangyue/p/4050258.html

    参考:http://www.cnblogs.com/wlflovenet/archive/2011/10/28/WCFREST.html

    2. 利用类BasicAuthenticationManager来解析BasicAuth http-header并且验证

    代码如下:

        public class BasicAuthenticationManager : ServiceAuthorizationManager
        {
            protected override bool CheckAccessCore(OperationContext operationContext)
            {
                try
                {
                    var msg = operationContext.RequestContext.RequestMessage;
    
                    // If user requests standart help-page then ignore authentication check.
                    if (msg.Properties.ContainsKey("HttpOperationName") && msg.Properties["HttpOperationName"].ToString() == "HelpPageInvoke")
                    {
                        return base.CheckAccessCore(operationContext);
                    }
    
                    var httpRequestHeaders = ((HttpRequestMessageProperty) msg.Properties[HttpRequestMessageProperty.Name]).Headers;
    
                    // Is Authorization-header contained in http-headers?
                    if (!httpRequestHeaders.AllKeys.Contains(HttpRequestHeader.Authorization.ToString()))
                    {
                        return false;
                    }
    
                    // Try to parse standart Basic-auth header.
                    var authenticationHeaderBase64Value = httpRequestHeaders[HttpRequestHeader.Authorization.ToString()];
                    var basicAuthenticationFormatString = Base64EncodeHelper.DecodeUtf8From64(authenticationHeaderBase64Value).Remove(0, "Basic ".Length);
                    var basicAuthenticationParams = basicAuthenticationFormatString.Split(new[] {':'}, 2);
                    var login = basicAuthenticationParams.FirstOrDefault();
                    var password = basicAuthenticationParams.LastOrDefault();
    
                    // Check credentials.
                    // 自定义验证方式:CAuthorizationAPI是自己封装的验证用户名和密码的方法类
                    if(!CAuthorizationAPI.Validate(login, password))
                    {
                        return false;
                    }                
                }
                catch (Exception ex)
                {
                    return false;
                }
    
                return base.CheckAccessCore(operationContext);
            }
        }
    对应的配置文件修改(behavior-section部分的修改)
     
    <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        <behaviors>
          <!--<endpointBehaviors>
            <behavior name="">
              <webHttp helpEnabled="true" faultExceptionEnabled="true" />
            </behavior>
          </endpointBehaviors>-->
          <serviceBehaviors>
            <behavior>
              <!-- 为避免泄漏元数据信息,
              请在部署前将以下值设置为 false 并删除上面的元数据终结点  -->
              <serviceMetadata httpGetEnabled="True" />
              <!-- 要接收故障异常详细信息以进行调试,
              请将以下值设置为 true。在部署前设置为 false 
                以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="true" />
              <serviceAuthorization serviceAuthorizationManagerType="DMService.Infrastructure.BasicAuthenticationManager, DMService" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    3. 写一个测试程序:增加basic auth http-header
    
     
        private static void Main(string[] args)
        {
            try
            {      
                var request = WebRequest.Create(string.Format("http://localhost:21568/api/test/yueyq/{0}", Uri.EscapeDataString("rest-client (ssl-basic auth)")));
    
                // ! Remove this string in production code. Emulate working with the trusted certificate.
                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    
                // The straightforward passing  of credential parameter for demo.
                const string login = "user";
                const string password = "password";
    
                request.Headers.Add(
                    HttpRequestHeader.Authorization,
                    Base64EncodeHelper.EncodeUtf8To64(string.Format("Basic {0}:{1}", login, password)));
    
                using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
                {
                    Console.WriteLine(reader.ReadToEnd());
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
    
            Console.WriteLine("
     press Enter to exit..");
            Console.ReadLine();
        }
    }
    
     
    4. 类Base64EncodeHelper的实现
     
    public static class Base64EncodeHelper
    {
        /// <summary>
        /// The method create a Base64 encoded string from a normal string.
        /// </summary>
        /// <param name="toEncode">The String containing the characters to encode.</param>
        /// <returns>The Base64 encoded string.</returns>
        public static string EncodeUtf8To64(string toEncode)
        {
            var toEncodeAsBytes = Encoding.UTF8.GetBytes(toEncode);
            var returnValue = Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }
    
        /// <summary>
        /// The method to Decode your Base64 strings.
        /// </summary>
        /// <param name="encodedData">The String containing the characters to decode.</param>
        /// <returns>A String containing the results of decoding the specified sequence of bytes.</returns>
        public static string DecodeUtf8From64(string encodedData)
        {
            var encodedDataAsBytes = Convert.FromBase64String(encodedData);
            var returnValue = Encoding.UTF8.GetString(encodedDataAsBytes);
            return returnValue;
        }
    }
    
    更多的关于WCF安全可以详细的查看下面链接:
    http://wcfsecurityguide.codeplex.com/
     
  • 相关阅读:
    Tarjan算法
    10JS数组
    9JS循环
    8.JS流程控制
    7.JS运算符
    6.JS方法
    5.JS变量的各种问题
    java封装遇到的问题
    js报Uncaught SyntaxError: Unexpected token <错误 解决方法:
    使用layui出现Uncaught ReferenceError: layui is not defined问题解决:
  • 原文地址:https://www.cnblogs.com/yongqiangyue/p/4050332.html
Copyright © 2020-2023  润新知