From reading the Microsoft docs on authentication with SignalR, it looks like the only way to authenticate using a bearer token is to send it in the query string on the WebSocket connection.
Upon inspecting the SignalR handshake, it looks like the Authorization header is included in the Negotiate call. Since the connection ID is returned in the negotiate response, the server could keep track of whether that connection ID has authenticated.
Why is it required to add the bearer token to the Websocket connection query string as well?
It seems this is the clue for your question.
When using WebSockets or Server-Sent Events, the browser client sends the access token in the query string. Receiving the access token via query string is generally secure as using the standard Authorization header. Always use HTTPS to ensure a secure end-to-end connection between the client and the server.
Security considerations in ASP.NET Core SignalR
This is the alternative:
SignalR can be used with ASP.NET Core authentication to associate a user with each connection. In a hub, authentication data can be accessed from the HubConnectionContext.User property. Authentication allows the hub to call methods on all connections associated with a user. For more information, see Manage users and groups in SignalR. Multiple connections may be associated with a single user.
Authenticate users connecting to a SignalR hub
Additional:
However, I think you can also try some injection for both server and client. On server eg. use websocket helper and on client eg. use Promise vs XMLHttpRequest.
Related
I'm using signalr core and am expect to be sending and receiving messages with the client frequently over mobile, so I've been trimming off the fat to minimize my message sizes. One thing I've simply been curious about is, when making requests from a hub that requires authentication, does every request sent to the hub also sends it's asp.net core authentication cookie, or does the client only send the cookie once when they initiate their connection to the hub and then all subsequent requests no longer need a cookie?
does every request sent to the hub also sends it's asp.net core authentication cookie, or does the client only send the cookie once when they initiate their connection to the hub and then all subsequent requests no longer need a cookie?
The cookies would be sent with the POST [endpoint-base]/negotiate request that is used to establish a connection between the client and the server, like below.
If a connection is established and the WebSockets transport is used, exchanging messages between server and client would be on WebSockets protocol.
If WebSockets is not available, and Long Polling transport is used, while client communicates with hub, cookies are sent with each request.
Besides, as mentioned in this doc: cookie authentication isn't recommended unless the app only needs to authenticate users from the browser client.
Background:
I have an application server that has an endpoint of /api/token. What this API does is it performs authentication against the supplied username and password using the standard basic authentication protocol.
When the process is successful, it returns an access token and HTTP code of 200 (OK). When fails, HTTP code 401 (unauthorised) is returned.
Question: Is there any way I can make Grafana's login page to pass on the login credential to my application server for authentication?
No, unless you want to hack source code.
But you can use Grafana in auth proxy mode, where authentication will be made by some "auth" proxy. For example, auth will be made by reverse proxy (e.g. Apache+mod_authnz_external) which will be in front of Grafana. All auth logic will be there and Grafana will just receive the request with request header X-WEBAUTH-USER value when user authentication is successful.
Another option is to start OIDC Identity Provider (for example Keycloak), which will use your app auth endpoint for authentication. Grafana has native OIDC/OAuth support, so it will be just configured against your OIDC Identity Provider.
One of a vendor API documentation mentions that their API calls require to use HTTP Basic Authentication scheme, i.e. user:password Base64 encoded but, their token API (Login equivalent) documentation mentions that "..this service implements OAuth 2.0 - Resource Owner Password & Credential Grant"
Isn't HTTP Basic Authentication different from OAuth ?
Yes, HTTP Basic Authentication different from OAuth 2.0. However, the Resource Owner Password Credentials Grant utilizes Basic Authentication Scheme within the Authorization Request for the Client's credentials as described with section 4.3.1. Authorization Request and Response
The Resource Owner Password Credentials Grant is typically used to convert legacy systems to OAuth 2.0 and no more secure than Basic Authentication Scheme.
Resource Owner Password Credentials Grant is intended to be used when no other Grant Types are available and ONLY when there is a high degree of trust between the Resource Owner and the OAuth Client .
Yes, they both are different.
Http Basic : This is for authentication and user credentials are encoded then passed in HTTP header to the client server.
Basic example for HTTP Basic : Just like traditional web application which asked user to provide credentials and these credentials sent to server in HTTP header. Later server utilize those credentials to authenticate the user.
OAuth 2 : This is for authorization, here the client server required authorization of user data(resource owner) from authorization server.
Basic example for OAuth 2 : Let say there is a online game application running on a server, the user accessed the application which starts loading into user's browser. Now that application asking grants from user to post data about games on his Facebook account. Here user authorize his that application to access his Facebook posts through OAuth Standard. Refer the internal mechanism https://www.rfc-editor.org/rfc/rfc6749
Basic access authentication usage is comparable to OAuth 2.0 Client Credentials Grant Type.
A session can be created using Basic Authentication and services can be accessed using a sessionid in a stateful environment.
But if you do not want to use the session due to session limitations or stateless services, you can use the OAuth 2.0 Client Credentials Grant Type instead, which creates a token instead of session and sessionid. This token provides access to the services.
HTTP basic access authentication:
This is the simpler method for meeting the requirements to access a web service. It is simple because it doesn’t require any of the usual processes in a credentials system: cookies, session IDs or access pages. The whole HTTP basic authentication process is based on standard fields in the HTTP header. Thus, it avoids handshaking: the automated process by which two entities establish authenticated communication before starting normal communication via the established channel. This means equipment can communicate with an external device only if there is successful authentication; otherwise, the communication channel is not created. The connection via modem would fail, for example. The secure development of the basic HTTP access authentication method is HTTPs.
To prevent the basic HTTP access authentication method causing the browser to launch a username and password request for each access, the browser must store this information in the cache for a prudent length of time that doesn’t reduce security excessively. These security credentials are usually stored for 15 minutes.
What is this basic HTTP access authentication method like in the real world?
The access credential provided to third-party developers who want to connect to a mobile API is a totally secret alphanumerical ID.
This alphanumerical API key is stored in a secure space on the server.
The developer making requests for a particular service contained in this API should place this secret ID within the HTTP authorization header along with the word Basic. The two elements together allow the server to recognize the alphanumerical credential and provide access.
GET /private/index.php HTTP/1.1
Host: example.com
Authorization: Basic alphanumerical ID
OAuth 2.0:
OAuth represents a step forward in the use of credentials for authentication of API service users. It is a major advance on the basic HTTP access authentication method. Today it is practically the only security method that is almost 100% reliable, and its reliability is based on creating unique authentication tokens for each user. If this access token is compromised, it is deleted and a new one is issued. This means that the API’s own credentials are safeguarded.
The authentication process is as follows:
A user launches a native application and is asked to give a username or email address and a password to identify themselves as a user.
The type of request used to send this credential to the API is a POST request, which ensures private delivery of secret data. This request is sent via the SSL (Secure Sockets Layer) protocol, designed to enable applications to transmit outbound data securely. SSL facilitates giving and receiving encryption keys between applications.
This request allows to validate user credentials and to create ad hoc an authentication or access token that will expire after a time, or if the user or developer responsible for the API believes it to have been breached.
This authentication token is stored in the device to facilitate access to the API’s services that support the application itself.
If we compare both methods, OAuth 2.0 provides better security criteria because any initial request for credentials is made under the SSL protocol and because the guaranteed access object is a temporary token. In the basic HTTP access authentication process, access to API services always relies on sending credentials via the web, specifically in the HTTP header, which makes it much vulnerable to third parties.
I have been trying to wrap my brain around authentication on a REST API.
I've tried to think of a way to successfully authenticate users, keeping in mind that users can access all data on the client, and I've come up with this idea.
Client sends username and password to the server
Server checks if they match a user.
If it does, we create a hashed string with user_id+e-mail+currentTime+salt
and stores this in a database-table with an expiration date.
Server returns hashed string to client
Client sends random request to server including key
Server checks if key is correct and if it's expired
Is this a proper way to do it, and do you see any security flaws?
You're effectively storing session state on the server, which is something you shouldn't be doing on a RESTful API.
Authentication on a RESTful API should simply follow whatever is the standardized authentication method for the underlying protocol. Instead of reinventing HTTP authentication, you should simply require clients to authenticate through HTTP Basic Auth on every request, using the Authorization header. Obviously, all your client-server interactions should be done over SSL.
If you really need some authentication token with an expire date, you can have a resource that provides it once the client is authenticated with basic (like a signed timestamp) but clients should still send that in the Authorization header, with a custom realm, and no state should be stored on the server.
I've been using wcf for a while and its authentication mechanisms, Windows, UserName/Password, Client certificate for a while.
I'd like to better understand how WCF uses these authentication mechanisms internally when creating SOAP messages and sending them.
Specifically, are the authentication credentials passed by wcf in every SOAP request, or does it only pass the authentication credentials in the first request and then some kind of token is issued and passed back and forth during subsequent sessions?
Are these authentication credentials (username+password, windows, client certificate) passed in a different manner depending on whether the security mode is transport or message? Is it that in message mode, the authentication credentials are inside the SOAP message, while in the transfer mode, http headers are other transport protocol specific are used to pass the authentication credentials?
Lets just assume that the SOAP message is secured using https when Transport mode is used and encrypted when using Message Mode and not worry about message privacy or tampering for this question.
You've asked several big qeustions, but I'll try to answer the question about sessions.
Session and authentication handling depend on the binding you're using. If you're using basichttpbinding, for instance, the host basically acts like a web server and no persistant "sessions" are created; as a result each SOAP request you send must contain everything necessary for authentication on the host. However, there are some bindings available like WSHTTPBinding that allow for the creation of security and reliability sessions that persist after the initial authentication using a token.
Wrapping the message in SSL should prevent problems.