diff --git a/websocket-sharp/Net/HttpListenerAsyncResult.cs b/websocket-sharp/Net/HttpListenerAsyncResult.cs index 286082b4..5df53e06 100644 --- a/websocket-sharp/Net/HttpListenerAsyncResult.cs +++ b/websocket-sharp/Net/HttpListenerAsyncResult.cs @@ -38,6 +38,7 @@ #endregion using System; +using System.Security.Principal; using System.Threading; namespace WebSocketSharp.Net @@ -114,42 +115,31 @@ namespace WebSocketSharp.Net if (schm == AuthenticationSchemes.Anonymous) return true; - var req = context.Request; - var authRes = req.Headers["Authorization"]; - - if (schm == AuthenticationSchemes.Basic) { - if (authRes == null || !authRes.StartsWith ("basic", StringComparison.OrdinalIgnoreCase)) { - context.Response.CloseWithAuthChallenge ( - AuthenticationChallenge.CreateBasicChallenge (listener.Realm).ToBasicString ()); - - return false; - } - } - else if (schm == AuthenticationSchemes.Digest) { - if (authRes == null || !authRes.StartsWith ("digest", StringComparison.OrdinalIgnoreCase)) { - context.Response.CloseWithAuthChallenge ( - AuthenticationChallenge.CreateDigestChallenge (listener.Realm).ToDigestString ()); - - return false; - } - } - else { + if (schm == AuthenticationSchemes.None) { context.Response.Close (HttpStatusCode.Forbidden); return false; } + var req = context.Request; var realm = listener.Realm; - context.SetUser (authRes, schm, realm, listener.UserCredentialsFinder); - if (req.IsAuthenticated) + var user = createUser ( + req.Headers["Authorization"], schm, realm, req.HttpMethod, listener.UserCredentialsFinder); + + if (user != null && user.Identity.IsAuthenticated) { + context.User = user; + req.IsAuthenticated = true; + return true; + } if (schm == AuthenticationSchemes.Basic) context.Response.CloseWithAuthChallenge ( AuthenticationChallenge.CreateBasicChallenge (realm).ToBasicString ()); - - if (schm == AuthenticationSchemes.Digest) + else if (schm == AuthenticationSchemes.Digest) context.Response.CloseWithAuthChallenge ( AuthenticationChallenge.CreateDigestChallenge (realm).ToDigestString ()); + else + context.Response.Close (HttpStatusCode.Forbidden); return false; } @@ -175,6 +165,46 @@ namespace WebSocketSharp.Net null); } + private static IPrincipal createUser ( + string response, + AuthenticationSchemes scheme, + string realm, + string method, + Func credentialsFinder) + { + if (response == null || + !response.StartsWith (scheme.ToString (), StringComparison.OrdinalIgnoreCase)) + return null; + + var res = AuthenticationResponse.Parse (response); + if (res == null) + return null; + + var id = res.ToIdentity (); + if (id == null) + return null; + + NetworkCredential cred = null; + try { + cred = credentialsFinder (id); + } + catch { + } + + if (cred == null) + return null; + + var valid = scheme == AuthenticationSchemes.Basic + ? ((HttpBasicIdentity) id).Password == cred.Password + : scheme == AuthenticationSchemes.Digest + ? ((HttpDigestIdentity) id).IsValid (cred.Password, realm, method, null) + : false; + + return valid + ? new GenericPrincipal (id, cred.Roles) + : null; + } + #endregion #region Internal Methods diff --git a/websocket-sharp/Net/HttpListenerContext.cs b/websocket-sharp/Net/HttpListenerContext.cs index fad63d70..c8dddd01 100644 --- a/websocket-sharp/Net/HttpListenerContext.cs +++ b/websocket-sharp/Net/HttpListenerContext.cs @@ -57,18 +57,13 @@ namespace WebSocketSharp.Net private HttpConnection _connection; private string _error; private int _errorStatus; + private HttpListener _listener; private HttpListenerRequest _request; private HttpListenerResponse _response; private IPrincipal _user; #endregion - #region Internal Fields - - internal HttpListener Listener; - - #endregion - #region Internal Constructors internal HttpListenerContext (HttpConnection connection) @@ -115,6 +110,16 @@ namespace WebSocketSharp.Net } } + internal HttpListener Listener { + get { + return _listener; + } + + set { + _listener = value; + } + } + #endregion #region Public Properties @@ -147,51 +152,16 @@ namespace WebSocketSharp.Net /// Gets the client information (identity, authentication, and security roles). /// /// - /// A that represents the client information. + /// A instance that represents the client information. /// public IPrincipal User { get { return _user; } - } - #endregion - - #region Internal Methods - - internal void SetUser ( - string response, - AuthenticationSchemes scheme, - string realm, - Func credentialsFinder) - { - var res = AuthenticationResponse.Parse (response); - if (res == null) - return; - - var id = res.ToIdentity (); - if (id == null) - return; - - NetworkCredential cred = null; - try { - cred = credentialsFinder (id); + internal set { + _user = value; } - catch { - } - - if (cred == null) - return; - - var valid = scheme == AuthenticationSchemes.Basic - ? ((HttpBasicIdentity) id).Password == cred.Password - : scheme == AuthenticationSchemes.Digest - ? ((HttpDigestIdentity) id).IsValid ( - cred.Password, realm, _request.HttpMethod, null) - : false; - - if (valid) - _user = new GenericPrincipal (id, cred.Roles); } #endregion diff --git a/websocket-sharp/Net/HttpListenerRequest.cs b/websocket-sharp/Net/HttpListenerRequest.cs index e28e6254..12d1ad88 100644 --- a/websocket-sharp/Net/HttpListenerRequest.cs +++ b/websocket-sharp/Net/HttpListenerRequest.cs @@ -59,6 +59,7 @@ namespace WebSocketSharp.Net private static readonly byte[] _100continue; private string[] _acceptTypes; + private bool _authenticated; private bool _chunked; private Encoding _contentEncoding; private long _contentLength; @@ -241,8 +242,11 @@ namespace WebSocketSharp.Net /// public bool IsAuthenticated { get { - var user = _context.User; - return user != null && user.Identity.IsAuthenticated; + return _authenticated; + } + + internal set { + _authenticated = value; } }