Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 通过HttpModule调用服务初始化函数_Asp.net_Wcf Data Services_Custom Authentication - Fatal编程技术网

Asp.net 通过HttpModule调用服务初始化函数

Asp.net 通过HttpModule调用服务初始化函数,asp.net,wcf-data-services,custom-authentication,Asp.net,Wcf Data Services,Custom Authentication,我已经编写了WCF数据服务,它在没有身份验证的情况下运行得非常好。 然后,我想通过在应用程序中添加HttpModule来添加一些身份验证代码,如下所示: public class BasicIdentity : IIdentity { string _name; public BasicIdentity(string name) { this._name = name; } string IIdentity.Authentication

我已经编写了WCF数据服务,它在没有身份验证的情况下运行得非常好。 然后,我想通过在应用程序中添加HttpModule来添加一些身份验证代码,如下所示:

public class BasicIdentity : IIdentity
{
    string _name;

    public BasicIdentity(string name)
    {
        this._name = name;
    }

    string IIdentity.AuthenticationType
    {
        get { return "Custom SCHEME"; }
    }

    bool IIdentity.IsAuthenticated
    {
        get { return true; }
    }

    string IIdentity.Name
    {
        get { return _name; }
    }
}

public class BasicPrincipal : IPrincipal
{
    string[] _roles;
    IIdentity _identity;

    public BasicPrincipal(string name, params string[] roles)
    {
        this._roles = roles;
        this._identity = new CustomIdentity(name);
    }

    public IIdentity Identity
    {
        get { return _identity; }
    }

    public bool IsInRole(string role)
    {
        return _roles.Contains(role);
    }
}

public class BasicAuthenticationProvider
{
    public static bool Authenticate(HttpContext context)
    {
        //if (!HttpContext.Current.Request.IsSecureConnection)
        //    return false;

        if (!HttpContext.Current.Request.Headers.AllKeys.Contains("Authorization"))
            return false;

        string authHeader = HttpContext.Current.Request.Headers["Authorization"];

        IPrincipal principal;
        if (TryGetPrincipal(authHeader, out principal))
        {
            HttpContext.Current.User = principal;
            return true;
        }
        return false; 
    }

    private static bool TryGetPrincipal(string authHeader, out IPrincipal principal)
    {
        // 
        // WARNING: 
        // our naive – easily mislead authentication scheme 
        // blindly trusts the caller. 
        // a header that looks like this: 
        // ADMIN username 
        // will result in someone being authenticated as an 
        // administrator with an identity of ‘username’ 
        // i.e. not exactly secure!!! 
        // 
        //var protocolParts = authHeader.Split(' ');
        //if (protocolParts.Length != 2)
        //{
        //    principal = null;
        //    return false;
        //}
        //else if (protocolParts[0] == "ADMIN")
        //{
        //    principal = new CustomPrincipal(
        //       protocolParts[1],
        //       "Administrator", "User"
        //    );
        //    return true;
        //}
        //else if (protocolParts[0] == "USER")
        //{
        //    principal = new CustomPrincipal(
        //       protocolParts[1],
        //       "User"
        //    );
        //    return true;
        //}
        //else
        //{
        //    principal = null;
        //    return false;
        //}
        var creds = ParseAuthHeader(authHeader);
        if (creds != null && TryGetPrincipal(creds, out principal))
            return true;

        principal = null;
        return false; 
    }

    private static string[] ParseAuthHeader(string authHeader)
    {
        // Check this is a Basic Auth header 
        if (
            authHeader == null ||
            authHeader.Length == 0 ||
            !authHeader.StartsWith("Basic")
        ) return null;

        // Pull out the Credentials with are seperated by ':' and Base64 encoded 
        string base64Credentials = authHeader.Substring(6);
        string[] credentials = Encoding.ASCII.GetString(
              Convert.FromBase64String(base64Credentials)
        ).Split(new char[] { ':' });

        if (credentials.Length != 2 ||
            string.IsNullOrEmpty(credentials[0]) ||
            string.IsNullOrEmpty(credentials[0])
        ) return null;

        // Okay this is the credentials 
        return credentials;
    }

    private static bool TryGetPrincipal(string[] creds, out IPrincipal principal)
    {
        if (creds[0] == "Administrator" && creds[1] == "SecurePassword")
        {
            principal = new GenericPrincipal(
               new GenericIdentity("Administrator"),
               new string[] { "Administrator", "User" }
            );
            return true;
        }
        else if (creds[0] == "JoeBlogs" && creds[1] == "Password")
        {
            principal = new GenericPrincipal(
               new GenericIdentity("JoeBlogs"),
               new string[] { "User" }
            );
            return true;
        }
        else
        {
            principal = null;
            return false;
        }
    }
}

public class BasicAuthenticationModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.AuthenticateRequest
           += new EventHandler(context_AuthenticateRequest);
    }
    void context_AuthenticateRequest(object sender, EventArgs e)
    {
        HttpApplication application = (HttpApplication)sender;
        if (!BasicAuthenticationProvider.Authenticate(application.Context))
        {
            application.Context.Response.Status = "401 Unauthorized";
            application.Context.Response.StatusCode = 401;
            application.Context.Response.AddHeader("WWW-Authenticate", "Basic");
            application.CompleteRequest();
        }
    }
    public void Dispose() { }
}
在此,BasicAuthenticationModule在web.config中注册为

 <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
    <httpModules>
      <add name="BasicAuthenticationModule"
     type="ODataEmptyWebApp.BasicAuthenticationModule"/>
    </httpModules>
 </system.web>

现在,当我在浏览器中运行WCF数据服务时,它会询问我身份验证窗口。 当我输入无效凭据时,它会不断询问正确的凭据,当我提供正确的凭据(即管理员/SecuredPassword)时,它会关闭窗口并显示空页面。该页面的源代码如下所示:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv="Content-Type" 
content="text/html; charset=windows-1252"></HEAD>
<BODY></BODY></HTML>

当我调试代码时,我发现它并没有调用我的WCF数据服务的Initialize方法,在我添加HttpModule之前,该方法经常被调用


我不明白为什么控件没有传递给Initialize方法。我是否必须明确添加一些东西才能使其运行???

我知道我在这里做错了什么,控件肯定应该通过,但无法找到控件泄漏的线路:(查看代码后,我建议使用WCF的隐式身份验证模式。Http模块不是服务的一部分,不会作为单个操作运行。