Modified HTTP auth for HttpListener class
This commit is contained in:
parent
55527ef514
commit
b521456dd6
@ -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<IIdentity, NetworkCredential> 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
|
||||
|
@ -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).
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="IPrincipal"/> that represents the client information.
|
||||
/// A <see cref="IPrincipal"/> instance that represents the client information.
|
||||
/// </value>
|
||||
public IPrincipal User {
|
||||
get {
|
||||
return _user;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
internal void SetUser (
|
||||
string response,
|
||||
AuthenticationSchemes scheme,
|
||||
string realm,
|
||||
Func<IIdentity, NetworkCredential> 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
|
||||
|
@ -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
|
||||
/// </value>
|
||||
public bool IsAuthenticated {
|
||||
get {
|
||||
var user = _context.User;
|
||||
return user != null && user.Identity.IsAuthenticated;
|
||||
return _authenticated;
|
||||
}
|
||||
|
||||
internal set {
|
||||
_authenticated = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user