SignalR oAuth on self host - asp.net-web-api

I have a webapi running on a self hosted app, security provided via oauth, and I'm setting the authorisation header for calling the API. This works great, we have a user identity on all calls.
Now I can pass the same authorization token by query string or cookie (or header on some connection types) to signalr (self hosted in the same app).
The token gets to the server for signalr, I can can add it into context.cookie, or into the headers.
but..nowhere can I get it to create an authenticated user, I seem to be plagued by 401 errors
I assume I am missing a key piece of code thats supposed to take the token and create an authenticated user for signalr (even though webapi/owin does it itself).
does anybody have any pointers, or examples where signalr works with oauth on self-host?

You are correct that you need to setup a way to authenticate and set the user when wanting to use SignalR with OAuth.
You can create a customer AuthorizeAttribute for SignalR.
In it you can basically get the query string to get hold of the token, once you have the token, you can unprotect it and start validating it and setting the user context in the request.
I have an example at
https://github.com/louislewis2/AngularJSAuthentication/blob/master/AngularJSAuthentication.API/SignalRHelpers/QueryStringBearerAuthorizeAttribute.cs
Once that has been implemented, you simply decorate your hub with [QueryStringBearerAuthorize]
The github link has a full working example for this and might provide some valuable insight.

Related

Elixir Phoenix Absinthe GraphQL API authentication in both web and mobile app's

I'm working on an Absinthe GraphQL API for my app. I'm still learning the procedure(so please go easy on me).
I've a Absinthe/GraphQL MyAppWeb.schema.ex file in which I use for my queries and mutations. My question is how do I use this API for authenticating the user on both Mobile and Web app?
How do set a cookie(httpOnly & secure) in my web app and access/refresh tokens in a single Absinthe API to serve my website and mobile app. Basically what I'm trying to learn is how do I authenticate the user based on specific platform.
If my question sounds bit confusing, I would be happy to provide more information related to my question. I would really be grateful if someone could explain the procedure, I've been very stuck on this for a while.
I would avoid using authentication mechanisms provided by absinthe(if there are any). Depending on what front-end you are using, I would go with JSON API authentication. The flow on server goes the following way:
Create a endpoint for login that will receive a user and password and will return a refresh token.
Create a endpoint for exchanging refresh token for access token.
Use a library like guardian to generate your refresh/access tokens.
Create a phoenix plug for authentication that will check your tokens, guardian has some built-in plugs for this.
Now on device you have to implement:
Ability to save refresh and access token on device.
Have a global handler for injecting access token on authorized requests.
Have a global handler for case when access token is expired. (you usually check if your request returns Unauthorized, then you should request a new access token from the server using your refresh token)
This seems like a crude implementation, however I would advise in implementing your system instead of using a black box library that you have no idea how it works under the hood.

How to access a secured API in the frontend?

There is a lot of good content on the internet that explains how to secure a Spring API with Keycloak: Create a Client that represents the API Service in Keycloak and use a link like the one below to get the access and refresh token:
<Domain>/auth/realms/<realm>/protocol/openid-connect/auth/{some parameters}
This yields both tokens. So far so good.
Now, however, I am not sure how the flow for the frontend accessing the API should look like.
Should the frontend directly access this endpoint and, therefore, obtain the access and refresh token? That would mean that the API can only have the access-type public because there is no way to store the client (the API) secret securely.
Or should there be a third server that somehow stores the refresh token for each user, that the user can call if his access token is no longer valid. This server would then use the client's refresh token (and the client secret that could be stored securely, since it would be in the backend) to get a new access token from Keycloak and would forward it to the user.
I guess the main question that I am asking is, whether the client/user should get the refresh token.
If one needs to implement a logic according to the second option, I would be interested in a link or description of how something like this can be done in Spring.
I think, in either case you need to use the Authorization Code Flow. The implicit flow, which was recommended for SPAs (frontends without a backend server) in former versions of OAuth2 must not be used anymore.
The best option is to have a backend server, so the user retrieves the auth code via redirection and the backend server exchanges this auth code with the access and refresh tokens (and keep them without forwarding them to the frontend).
If there is no backend in place and your frontend needs to retrieve and hold the tokens directly, I would recommend to use the Authorization Code Flow with a public client and the PKCE extension (which - put simply - ensures that the entity asking for the auth code is the same as the entity asking for the tokens and that the auth code was not stolen and used by a foreign entity). There are several sources with more detailed explanations, which might help you, for example: https://auth0.com/docs/flows/authorization-code-flow-with-proof-key-for-code-exchange-pkce
Hope this helps you with your architectural considerations.

Securing web app and api using OpenID Connect

I don't want to roll my own security anymore and am looking at using OpenID Connect with my c# API and AngularJS app. I can get all that to work just fine. However, my brain cannot seem to understand how to secure my API correctly for both use cases:
Use Case 1: AngularJS SPA
My AngularJS app connects to my API and sends a bearer token identifying the user and includes user claims. This one is easy and there is tons of documentation on it.
Use Case 2: API to API
Some customers want to access my API directly instead of going through my AngularJS app. In this case, I thought I could use a Client ID/Secret for toen-based authentication which is great except then I know nothing about the user that's using the client id/secret. There could be 10 users using the same custom API that is calling my API. How do I get user info via the API call? I've seen others use API keys that they then lookup the user and create a JWT but I thought there might be an easier way. Any ideas?
The whole point of API to API authentication is that there is no user context. Or well, the user in that case is the machine trying to access your API. You would then need to design your authorization logic around that and implement scope based permissions. Alternatively, your options are to use api keys as you mentioned or if you want OAuth protocol with user context in the api to api scenario - then ResourceOwnerCredentials flow is an option.
API to API communcation
You can use Client Credentials Grant defined through OAuth 2.0. This won't require you to have end user credentials. Now this won't be OpenID Connect. OpenID Connect require the involvement of an end user and bound to authentication. OAuth 2.0 on the other hand is about authorization, checking whether the entity can access the resource.
With Client Credential Grant, your identity server will issue tokens for a specific client. So one of your API becomes the client (resource consumer). From request handling API endpoint, you can accept valid tokens and respond back with resource.
If you require fine grained access control from request handling API, you will require to use token introspection to identify to whom this token was issued. In this case, it will be identification of specific client identity and execute a logic on top of it. You can check the token introspection response to identify such details.
Alternatively, access tokens can be come in form of a JWT. If this is the case, they can be considered as self contained tokens so validation is straightforward.

How to provide login authentication for Web API in Xamarin App?

I am working on Xamarin Forms application and new to providing login authentication of the application. I have completed the design part of the application with using Entries for user id and password and button for Submit. Also, i am having web API and for authentication. Now how to connect that Web API in xamarin forms application for login.
Please guide or provide some use full samples...
Thanks in advance...!
I assume you've built out your authentication API already, and that you can make Fiddler or Postman calls directly to your controller, pass in a set of credentials, and return back a JWT / bearer token that you can then use for authenticated calls?
At this point, it's relatively simple then as you'll want to use build a proxy layer / API layer to make calls out to your API. These calls will simply mirror the ones you've made in Fiddler/Postman/your proxy of choice.
I used Refit to achieve this:
https://github.com/reactiveui/refit
Specifically, you can see on the "Setting request headers" section how they easily encapsulate it for you to pass your token.
Of course, your initial call should be to login, and then once logged in, take the JWT response back from your controller, set the token in your Keychain, and then pull it out of Keychain to set in the header.
Let me know specific questions you have? For example, which of the following do you need more info on?
Sending and parsing a response (serializing the response) from your Login action to set/assign a token in keychain?
Saving the token, and setting it in a header for subsequent calls?
Building a proxy layer using a framework like Refit to make generic outbound calls?

Using Xamarin.Auth with a custom endpoint/webservice

I'm implementing a login auth in my app. For now I'm using an IOC interface which stores my email and password in the device storage (It uses the SharedPreferences in Android and the NSUserDefault class in iOS). When I go to the login screen I must put my email and my password, then I send that data to the server API. The server response is an authentication token, set in the request "Set-Cookie" header. I must set this auth token in every request that I make to the server API. The token expires after certain amount of time, value which comes also in the request header. Basically everything is working OK now, but the issue is that as we know, saving sensitive data like the user email and password in the SharedPreferences/NSUserDefaults is not a good idea. So I was wondering if I can achieve this using Xamarin.Auth. AFAIK Xamarin.Auth only works with identity providers such as Facebook, Google, OAuth, etc.
Is this possible? Can I user Xamarin.Auth to securely save this values?
This should definitely work, take a look at the GitHub repository of Xamarin.Auth.
The "getting started" page states that you can easily extend/customize Xamarin.Auth to work with your endpoint:
Xamarin.Auth includes OAuth 1.0 and OAuth 2.0 authenticators,
providing support for thousands of popular services. For services that
use traditional username/password authentication, you can roll your
own authenticator by deriving from FormAuthenticator.
If you want to authenticate against an ostensibly unsupported service,
fear not – Xamarin.Auth is extensible! It's very easy to create your
own authenticators – just derive from any of the existing
authenticators and start overriding methods.

Resources