When you say I have to provide my own implementation, do you mean implement onLoginNeeded event? Or replace RestSchemaDispatcher with my own implementation?
Well, let’s look at this closer. All you actually need is to be able to call the REST dispatcher with your JWT session token and be able to actually execute the data requests. The issue is that RestSchemaDispatcher doesn’t understand JWT.
Take a look at this Schema Dispatcher implementation. It takes an incoming request, processes its JWT token and then passes it further. Wrapper classes are required to allow us to override the HTTP header values (particularly the one expected by the existing Schema Dispatcher)
public class JwtRestSchemaDispatcher : RestSchemaDispatcher
{
public IApiAuthenticationManager AuthenticationManager { get; set; }
public override void Process(IHttpRequest request, IHttpResponse response, Stream requestData, Stream responseData)
{
IApiSession apiSession;
try
{
apiSession = this.AuthenticationManager.ReadAuthenticationInfo(request);
}
catch (Exception)
{
this.WriteNotAuthorized(response, responseData);
return;
}
try
{
var requestWrapper = new RequestWrapper(request, apiSession.SessionId);
base.Process(requestWrapper, response, requestData, responseData);
}
finally
{
// This call is required to let the authentication manager properly finalize the session
// However at this pint we do not have an IApiMessage instance
// So make sure that your Auth Manager implementation is able to properly manage WriteAuthenticationInfo
// calls where IApiMessage instance was not provided
this.AuthenticationManager.WriteAuthenticationInfo(response, null, apiSession);
}
}
}
sealed class RequestWrapper : IHttpRequest
{
private readonly IHttpRequest _request;
public RequestWrapper(IHttpRequest request, Guid sessionId)
{
this._request = request;
this.Header = new HeaderWrapper(request.Header, sessionId);
}
public IHttpHeader Header { get; }
public string Method
{
get
{
return this._request.Method;
}
}
public string TargetUrl
{
get
{
return this._request.TargetUrl;
}
set
{
this._request.TargetUrl = value;
}
}
public string ContentType
{
get
{
return this._request.ContentType;
}
}
public string QueryString
{
get
{
return this._request.QueryString;
}
}
public bool UsesAuthentication
{
get
{
return this._request.UsesAuthentication;
}
set
{
this._request.UsesAuthentication = value;
}
}
public string AuthUsername
{
get
{
return this._request.AuthUsername;
}
set
{
this._request.AuthUsername = value;
}
}
public string AuthPassword
{
get
{
return this._request.AuthPassword;
}
set
{
this._request.AuthPassword = value;
}
}
public string GetQueryString(string value)
{
return this._request.GetQueryString(value);
}
}
sealed class HeaderWrapper : IHttpHeader
{
private readonly IHttpHeader _header;
private readonly Guid _sessionId;
public HeaderWrapper(IHttpHeader header, Guid sessionId)
{
this._header = header;
this._sessionId = sessionId;
}
public string this[string name]
{
get
{
return (name == @"sessionid") ? (string)this._sessionId.ToString() : this._header[name];
}
set
{
// Left empty
}
}
}