SignalR seems to not be using the root path that I give it when trying to connect - sockets

I have my SignalR server listening on the following URL:
http://staging.myserver.com/socket/signalr
I tested locally and it works, but when I deploy, I am running through an NGINX proxy (hence the /socket/)
When it tried to connect to the deployed SignalR server, it is failing and I can see that it is attempting to connect using a URL with the /socket/ ommitted.
I have tried to debug to see if there is a sport where it strips everything but the base url and appends /signalr but I can't seem to find anything.
I am able to hit the following URL and see my hubs perfectly fine.
http://staging.myserver.com/socket/signalr/hubs
I just don't know why it is omitting the /socket from the url when trying to connect.
Here is more or less an example of what I have
var connection = $.hubConnection('http://staging.myserver.com/socket/signalr');
var contosoChatHubProxy = connection.createHubProxy('contosoChatHub');
contosoChatHubProxy.on('addContosoChatMessageToPage', function(name, message) {
console.log(name + ' ' + message);
});
connection.start().done(function() {
//blah blah
});
I can see it taking the correct URL when it first initializes the connection, but somewhere along the way, it defaults back to
http://staging.myserver.com/signalr
The only way I have been able to get around it is by adding an addition proxy to / on my NGINX proxy. This is not something that will be able to stick so I need to figure it out.

Please see GitHub issues #3649 and #3287 which describe the same issue and give some pointers specific to IIS on how to transform the content within the response to the connection negotiation to re-write the URL property. It appears that the URL within the response from the server is used to set a local variable called appRelativeUrl on the client side which is used for subsequent interaction. So another less palatable workaround is to modify/configure the SignalR server using app.MapSignalR("/socket/signalr", hubConfiguration); but I haven't gone that route to see whether it would cause other problems.

Related

flask-jwt-extended - Catch raise RevokedTokenError('Token has been revoked')

I already tried reading the documents as well try out the changing default behaviors https://flask-jwt-extended.readthedocs.io/en/latest/changing_default_behavior.html to handle the error (the link shows how to handle expired token) and search around in google everything in every keyword combination i could do but seems no one has example about this.
I tried using #jwt.revoked_token_loader to handle the RevokedTokenError but it seems it doesn't work as I applied it like this
#jwt.revoked_token_loader
def revoked_token_response(revoked_token):
jwtkn = revoked_token['jti']
return jsonsify({
'msg': 'token {} already been revoked!'.format(jwtkn)
)}, 401
actually, i don't know exactly how does the example on the link to handle expired tokens had parameter of 'expired_token', is that self-declaration like what I did above on the 'revoked_token'?? as far as I know, 'jti' is like a default value in the flask-jwt-extended package as I see error whenever I don't use this (in my db, it is different but there is no problem at all.
I tried following this tutorial and it works out fine on my side (as well his original code source) but I see that this one doesn't have a catch exception also on Revoke Tokens https://codeburst.io/jwt-authorization-in-flask-c63c1acf4eeb
I use postman and if based on the tutorial link, here's how i get this
i do login
i use the access token generated to access protected routes ('/secrets')
i do logout
i use again the access token generated to access protected routes
after the last one, i get this error on my server side (ide):
....flask_jwt_extended\utils.py", line 216, in verify_token_not_blacklisted
raise RevokedTokenError('Token has been revoked')
flask_jwt_extended.exceptions.RevokedTokenError: Token has been revoked
127.0.0.1 -- [02/Jul/2019 22:25:26] "GET /secrets HTTP/1.1" 500 -
in postman, this is what I get:
{
'message': 'Internal Server Error'
}
my target is to send out a custom json response instead of 'Internal Server Error'
edit:
I am no wiz on programming or such, a beginner that wanted to practice out python about secured web development. I don't yet quite understand still how decorator works out in terms of application, etc. so i don't know if others tweaks out the flask-jwt-extended package to work such things out.
Getting back a 500 error normally occurs because of a bug in other flask extensions and how that interact with native flask errorhandlers. You can find a bunch of discussions about it here (https://github.com/vimalloc/flask-jwt-extended/issues/86), but the tl;dr version is you might need to set app.config['PROPAGATE_EXCEPTIONS'] = True if using something like Flask-Restul, or use a hack like this if using flask-restplus:
jwt = JWTManager(app)
api = Api()
jwt._set_error_handler_callbacks(api)
If those don't help you, please take a look through that linked github issue, and if nothing in there helps make a reply in that issue detailing your setup.
Cheers.

Pass Windows Credentials to a RESTful Web API using Windows.Web.Http.HttpClient

I know this question was asked time and again, here and here. The answers given are pretty much the same, but in my case I still miss something and I cannot figure out exactly what it is. I have a RESTful Web API deployed and that is configured to accept only domain-authenticated calls. So on my client side, in my UWP application, I used the HttpClient class from the Windows.Web.Http namespace. The resources found online all show that I need to do two things:
Enable Enterprise Authentication in the package manifest of my UWP app. I did that. Here is a screen shot of the capabilities selected for my app:
Set the "AllowUI" flag to be false, so that the user is not prompted to enter its credentials. I did that too. Here is a code snippet of what I am doing:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter { AllowUI = false };
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
With this code in place, I don't get prompted for the credentials, but the response.IsSuccessStatusCode flag comes back as false and the error that I get is 401 - Unauthorized.
Before you ask, yes, the server-side endpoint is properly configured and works fine. If I try this:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter();
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
I am asked for my credentials and when I enter them correctly, I get a proper HTTP 200 code in response. I also tried this:
Uri uri = new Uri(_myUriRoute);
var filter = new HttpBaseProtocolFilter
{
AllowUI = false,
ServerCredential = new PasswordCredential(_myUriRoute, _myUserName, _myPassword)
};
var httpClient = new HttpClient(filter);
HttpResponseMessage response = await httpClient.GetAsync(uri);
and again, I get a nice HTTP 200.
So what am I missing? I don't want to be prompted and I don't want to store credentials either. I want to have Windows pass automatically the credentials of the current user of the app.
Two things worth mentioning. The above-described behavior happens in my development environment (Visual Studio 2017) while I try debugging/running my app using the "Local Machine" option. Also, the first thing that happens when I start the app is I am prompted to grant permissions to the app to access the pictures folder and account info:
This happens despite the fact that I have selected "User Account Information" among the Capabilities set for the application, as can be seen in the above screen shot of the Capabilities tab, in the application's package manifest.
Any idea of what is missing? Any idea of what else should be tried?
Any suggestion will be highly appreciated.
Cheers,
Eddie
PS: I posted the same question on the MSDN Forums as well
PS2: The Web API is running in IIS Express, started from Visual Studio 2017, in a different instance. I configured IIS Express to expose my Web API using the IP address of my development machine instead of the "localhost". In its web.config file, I have the following setting:
<system.web>
<authentication mode="Windows"/>
</system.web>
I post this, just in case the issue is on the Server side, which I think it isn't.

Cookies set in Windows.Web.Http.HttpRequestMessage are ignored on redirects

I'm using HttRequestMessage, and adding a cookie in an IHttpFilter as follows:
public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
{
var c = new HttpCookiePairHeaderValue("SSOAutologonCertificate", "true");
request.Headers.Cookie.Add(c);
return InnerFilter.SendRequestAsync(request);
}
Using Fiddler I can see that the cookie is correctly added to the outgoing request. However, the reply is an auto-redirect. When fiddler captures that outgoing request, that cookie is no longer set in the http header - it seems to have been forgotten.
Is this expected behavior? Or a bug? If it is expected behavior, is there anything I can do to alter it?
If, on the other hand, I add the cookie to the Cookie collection on a HttpBaseProtocolFilter object, then everything works as expected, and the cookie is there for every auto-redirect query. Of course, while that will work for now, that totally defeats the purpose of a IHttpFilter. :-) This behavior was observed on a windows store app (running on Windows 10 tech preview).
BTW, I spent some time trying to figure out how to step into the .NET source for the Windows.Web.Http namespace, but nothing seemed to work (I can into other .NET source). Is there a special trick for these windows component files (the module is Windows.Web.winmd).
Thanks in advance!

redirect_uri and how to host callback.html on SoundCloud?

I am trying to access Soundcloud from a local HTML page on my laptop. I am stuck at the part of hosting "callback.html" as a redirect_uri. The script I am trying to run is the basic Authenication JavaScript from the Soundcloud documentation page:
<script src="http://connect.soundcloud.com/sdk.js"></script>
<script>
// initialize client with app credentials
SC.initialize({
client_id: 'my_client_id',
redirect_uri: 'http://127.0.0.1/Users/Maria/Documents/SoundcloudClient/callback.html'
});
// initiate auth popup
SC.connect(function() {
SC.get('/me', function(me) {
alert('Hello, ' + me.username);
});
});
</script>
This script gets me to the connect pop-up when I launch the page in Chrome and Firefox.
But, once I have logged in as a Soundcloud user, I get the following error:
Oops! Google Chrome could not connect to 127.0.0.1
If I change my redirect_uri to localhost I get the same error.
If I try:
files:///C:/Users/Maria/Documents/SoundcloudThinClient/callback.html
I get a similar error.
I also tried:
ocalhost:3000
and:
localhost:8080
even though I'm not sure what would be listening on those ports.
So, basically, I'm asking what path do I put for callback.html in order for this to work?
I confess I don't know how the redirct_uri actually functions. I looked at the Oauth pages for it, but I don't understand them. I am beginning to think that I can't simply create an HTML page, paste the JavaScript, create a callback.html file and have this work, even though the SC documentation seems to say that this is possible. If so, what steps am I missing?
I am beginning to attempt this. I believe you have to go to the developer site and sign up as having an app. The redirect uri is asked for and the form gives you an API key you can use in your app.
I'm using drupal so, perhaps adding the oath module and using Php to add the api key might work well.
I had the same problem and I think I solved it.
Morning-after-edit: I posted this dead-tired after working towards a solution through the night. Now, the day after, I realize that you were speaking about the general problem, whereof I face a very particular instance. The following only applies directly to registering soundcloudlabs' soundcloud-group-recorder: https://github.com/soundcloudlabs/soundcloud-group-recorder. There is probably a more general principle lurking behind there, though:
First: yes, you do have to register the app as your own at Soundcloud. At least I presumed so. And doing that, you must register correctly where on your server you will place the callback.html file. Take the ClientID assigned to your app and use that in the API intialize procedure.
Now, I'm a novice and know very little coding. But I started looking around in the main file, application.js.
At the top of the file there are two instances of client_id and redirect_uri each. I'm not sure if that serves a purpose or if one is technically superfluous. Through trial and error I found out that replacing the second instance of each with my own data worked.
Then there is groupId and groupUrl, both of which should contain your info, within quotation marks.
After a lot of trial and error, still having trouble getting the thing to run, I looked around and saw that, whereas early in the file, client_id was hooked within SC.initialize, redirect_uri was not. Under the line:
client_id: CLIENT_ID
I added:
redirect_uri: REDIRECT_URI
– with a customary comma in between. And that's it. It runs.

Why GWT URL doesn't change on an event or a service call?

I have two questions:
Q: 1
I'm currently developing a GWT app. The entry point for the app is: ImageViewer.java. I could well access it by http://127.0.0.1:8888/ImageViewer.html?gwt.codesvr=127.0.0.1:9997. I have a service called "Search" which has corresponding "Async" and "Impl"'s defined. Now, I call the service from client side, using RPC. I could call the service, obtain return value. Everything works fine.
However, I expect the application to show a behavioral change on URL. i.e. when a service is being accessed, I thought it would be reflected on the browser's URL something like: http://127.0.0.1:8888/search?gwt.codesvr=127.0.0.1:9997 as I've modified web.xml. However, this behavior is not realized. Any particular reason why this is not reflected??
Q:2
This one is a reverse of the previous ques. i.e. I have an application running. Let's say it has an entrypoint class(Imageviewer.java) and another composite class (searchClass.java) which would be loaded on the Imageviewer based on an event. This searchClass invokes the "search" service mentioned in the previous question.
I could load the "searchClass" in "Imageviewer", invoke the service, and the service also returns the value needed. Everything works fine... But,
I need something like this: by just typing this query string:
http://127.0.0.1:8888/search?value=John
I want the "searchClass" to be loaded on the "ImageViewer", call the service using the value(which is "john" in this case) and display the result. Is this possible at all?
what I've tried: I have tried to create a httpServletClass on the server and mapped it with the URL and could do the search. The search returns appropriate results. However, I want the results from the server to be displayed on the client. Remember, I'm directly using a servlet to read the URL and so there is no value being passed from client to server.
Thanks in advance.
A: 1. To change URL, the hash part, you need to set new history token in the History class. More about history management in this article.
A: 2. For the second part you could achieve it by changing the history token, for instance "http://127.0.0.1/search#value=John". The history service will trigger an event if the # part changes. You could also use the part with "?", as in your example, if you use Window.Location , but it will cause reload of the application, which would put the whole idea of using GWT in question.
RPC (AJAX) calls are done Via XHR and do not change the browser URL.
You can't (with the URL you presented). GWT apps normally run in one web page, i.e. the URL does not change (see how gmail changes browser url bar). What you can do is enable GWT history support. Then your url would be http://host/#search?value=queryu