From 533ef2090a1cd29a1fcfb2e68400f19553e3a287 Mon Sep 17 00:00:00 2001 From: sta Date: Sat, 22 Nov 2014 14:46:42 +0900 Subject: [PATCH] Modified HTTP auth for WebSocketServer class --- .../Net/HttpListenerAsyncResult.cs | 42 +----------------- websocket-sharp/Net/HttpUtility.cs | 41 ++++++++++++++++++ .../WebSockets/TcpListenerWebSocketContext.cs | 43 +++++-------------- websocket-sharp/Server/WebSocketServer.cs | 35 +++++++-------- 4 files changed, 68 insertions(+), 93 deletions(-) diff --git a/websocket-sharp/Net/HttpListenerAsyncResult.cs b/websocket-sharp/Net/HttpListenerAsyncResult.cs index 5df53e06..17b283a5 100644 --- a/websocket-sharp/Net/HttpListenerAsyncResult.cs +++ b/websocket-sharp/Net/HttpListenerAsyncResult.cs @@ -122,7 +122,7 @@ namespace WebSocketSharp.Net var req = context.Request; var realm = listener.Realm; - var user = createUser ( + var user = HttpUtility.CreateUser ( req.Headers["Authorization"], schm, realm, req.HttpMethod, listener.UserCredentialsFinder); if (user != null && user.Identity.IsAuthenticated) { @@ -165,46 +165,6 @@ 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/HttpUtility.cs b/websocket-sharp/Net/HttpUtility.cs index ade29b1f..c5cd117e 100644 --- a/websocket-sharp/Net/HttpUtility.cs +++ b/websocket-sharp/Net/HttpUtility.cs @@ -46,6 +46,7 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Globalization; using System.IO; +using System.Security.Principal; using System.Text; namespace WebSocketSharp.Net @@ -548,6 +549,46 @@ namespace WebSocketSharp.Net return res; } + internal 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; + } + internal static Encoding GetEncoding (string contentType) { var parts = contentType.Split (';'); diff --git a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs index c71c3a6a..bfc988ca 100644 --- a/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs +++ b/websocket-sharp/Net/WebSockets/TcpListenerWebSocketContext.cs @@ -105,6 +105,12 @@ namespace WebSocketSharp.Net.WebSockets #region Internal Properties + internal string HttpMethod { + get { + return _request.HttpMethod; + } + } + internal Stream Stream { get { return _stream; @@ -159,7 +165,7 @@ namespace WebSocketSharp.Net.WebSockets /// public override bool IsAuthenticated { get { - return _user != null && _user.Identity.IsAuthenticated; + return _user != null; } } @@ -304,7 +310,7 @@ namespace WebSocketSharp.Net.WebSockets /// Gets the client information (identity, authentication, and security roles). /// /// - /// A that represents the client information. + /// A instance that represents the client information. /// public override IPrincipal User { get { @@ -359,38 +365,9 @@ namespace WebSocketSharp.Net.WebSockets _request = HttpRequest.Read (_stream, 15000); } - internal void SetUser ( - AuthenticationSchemes scheme, - string realm, - Func credentialsFinder) + internal void SetUser (IPrincipal value) { - var authRes = _request.AuthenticationResponse; - if (authRes == null) - return; - - var id = authRes.ToIdentity (); - if (id == null) - return; - - NetworkCredential cred = null; - try { - cred = credentialsFinder (id); - } - 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); + _user = value; } #endregion diff --git a/websocket-sharp/Server/WebSocketServer.cs b/websocket-sharp/Server/WebSocketServer.cs index 71e52b8b..18476957 100644 --- a/websocket-sharp/Server/WebSocketServer.cs +++ b/websocket-sharp/Server/WebSocketServer.cs @@ -543,13 +543,16 @@ namespace WebSocketSharp.Server _state = ServerState.Stop; } - private bool authenticateRequest ( - AuthenticationSchemes scheme, TcpListenerWebSocketContext context) + private static bool authenticate ( + TcpListenerWebSocketContext context, + AuthenticationSchemes scheme, + string realm, + Func credentialsFinder) { var chal = scheme == AuthenticationSchemes.Basic - ? AuthenticationChallenge.CreateBasicChallenge (Realm).ToBasicString () + ? AuthenticationChallenge.CreateBasicChallenge (realm).ToBasicString () : scheme == AuthenticationSchemes.Digest - ? AuthenticationChallenge.CreateDigestChallenge (Realm).ToDigestString () + ? AuthenticationChallenge.CreateDigestChallenge (realm).ToDigestString () : null; if (chal == null) { @@ -558,9 +561,6 @@ namespace WebSocketSharp.Server } var retry = -1; - var schm = scheme.ToString (); - var realm = Realm; - var credFinder = UserCredentialsFinder; Func auth = null; auth = () => { retry++; @@ -569,19 +569,16 @@ namespace WebSocketSharp.Server return false; } - var res = context.Headers["Authorization"]; - if (res == null || !res.StartsWith (schm, StringComparison.OrdinalIgnoreCase)) { - context.SendAuthenticationChallenge (chal); - return auth (); + var user = HttpUtility.CreateUser ( + context.Headers["Authorization"], scheme, realm, context.HttpMethod, credentialsFinder); + + if (user != null && user.Identity.IsAuthenticated) { + context.SetUser (user); + return true; } - context.SetUser (scheme, realm, credFinder); - if (!context.IsAuthenticated) { - context.SendAuthenticationChallenge (chal); - return auth (); - } - - return true; + context.SendAuthenticationChallenge (chal); + return auth (); }; return auth (); @@ -642,7 +639,7 @@ namespace WebSocketSharp.Server try { var ctx = cl.GetWebSocketContext (null, _secure, _sslConfig, _logger); if (_authSchemes != AuthenticationSchemes.Anonymous && - !authenticateRequest (_authSchemes, ctx)) + !authenticate (ctx, _authSchemes, Realm, UserCredentialsFinder)) return; processWebSocketRequest (ctx);