WebApi Support Implict Flow (with roles) and Client Credential Grant - asp.net-web-api

I have a situation I haven't run into yet and wondering if I need to write a custom authorize attribute to handle this situation or if there is something in the identity framework I should be using.
I need to support both Implicit flow (mostly for swaggerUI integration) and client credential grant in my webapi. The data I'm working with is sensitive and therefore I don't want anyone who discovers my swagger page and can authenticate with my AAD instance (through an implicit flow) to be able to consume my data. I want to restrict the my api to look for roles in the jwt IF THEY ARE PRESENT.
On the flip side my WebApi is most likely going to be consumed by other services. So I need to support client credential flow. Obviously the tokens issued through the client credentials grant will not have a role claim, so I can't look for roles when I authorize these requests.
I'm basically looking for something like this:
[Authorize(Roles = "swagger_admin", Optional=true)]
public class UserController : ApiController
{
But I'm not seeing something logically equivalant, and before I go out and write a custom authorize attribute I want to know what others have done here.
Thanks!

Related

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.

Can Okta be used for an API that will be accessed programmatically?

I am trying to understand if the following scenario can be accomplished using an Okta developer account. I want to secure an API written in Python/Flask that is meant to be accessed programmatically by another backend service. No user interaction. So far, all I am able to find are tutorials where a user is redirected to a login screen and must manually enter credentials.
I was thinking maybe I could call the http://USERNAME.okta.com/api/v1/authn endpoint. I did this with Postman and successfully authenticated and was given a session ID. Can this session ID be used to access an API endpoint I have written that is protected with the "#login_required" decorator?
Ideally I would like the flow to be something along the lines of this.
Service A wants to consume my Okta protected API.
Service A calls an endpoint providing credentials it has stored somewhere secure. (The user never sees a login screen / enters credentials / even is aware of the Okta protected API's existence)
My Okta protected API authenticates the credentials via Okta and provides back a bearer token.
Service A then provides this token when making requests to the Okta protected API
I've seen this flow plenty of times when developing against third party API's. Is it possible to accomplish this with Okta? if so, could someone point me to an example of how this can be done?
Thank you
Many grant flows can be used to authenticate an application instead of a user.
You could use the client credentials flow for instance.
See Okta documentation for more details.
Here is a sample in python using requests-auth (authentication classes to be used with requests). If you are using httpx instead of requests you can use httpx-auth.
import requests
from requests_auth import OktaClientCredentials
okta = OktaClientCredentials(instance='testserver.okta-emea.com', client_id='54239d18-c68c-4c47-8bdd-ce71ea1d50cd', client_secret="secret")
requests.get('http://www.example.com', auth=okta)

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.

SignalR oAuth on self host

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.

Simple Web Token (SWT) Authentication in Web Api 2 OData endpoint

Ok, the situation is this.
We already have an existing ASP.NET MVC 5 site with Custom Forms Authentication, Logon, Registration etc with a custom database for roles and profiles already implemented.
We now are adding some new functionality to the MVC site and we decided to use Web Api 2 OData 3 endpoint which lives in another domain. The Web Api currently doesn't include any authentication but we need to be able to map the requests to a certain user to get his roles etc from the backend. The MVC and API sites use the same backend.
What we would like to accomplish is, that when the user logs on in the MVC site, the MVC site calls the Web Api server-to-server with the user's credentials and receives a token that the client can then use to call the web service with.
When API receives a request with the token, it can then map the request with the user in backend and do authorization.
As far as I understand it, Simple Web Token (SWT) could pull it through. But considering the environment, .NET 4.5.1 / Web Api 2 / OData 3 with Entity Framework in Azure Web Role, I started thinking is this SWT something I should really use or if there is any NEW technologies recently published that could easily pull this through. I don't want to add any unnecessary 3rd party dependencies to the project if the .NET stack already contains something like it.
So, what would be the simplest way of pulling this kind of authentication through without adding unnecessary dependencier to the project.
The solution we are looking for, is only temporary meanwhile we redesign our authentication scheme. So we are looking for something really simple to implement that works with least dependencies that need to be removed later on.
I'm using this in a project I'm currently working on. I use the OAuth 2.0 OWIN Middleware component that ships with Web API 2.0 (if you add a new Web API project with Authentication enabled, it includes the base infrastructure).
You would use the Resource Owner Password Flow as defined in the OAuth 2.0 specification. Basically you request a Token from the Web API OWIN Middleware sending:
client_id - identifies your MVC endpoint
client_secret - identifier your MVC endpoint
username
password
And in response you get a bearer token. The token generating is based upon a claims principal, the OAuth middleware component has predefined hooks for adding claims. This token now needs to be added as authorisation header to each response. On the MVC side you might add this to session so that it's always available to make backend API calls in the context of the user associated with an incoming HTTP request. If you're using WCF Data Services Client, you'll need an authorisation service/manager or similar that you can hook into OnRequestSending and OnResponseReceived events, so that you can insert that bearer token into the HTTP headers.
You can customise the OAuth Middleware component as you need to quite easily, it took a bit of time to figure it out as it's not too well documented, but downloading the Katana source code did help a bit as the source code does have some good documentation.
The nice thing about it all is that you simply need to enable HostAuthenticationFilter and add Authorize attributes on the Web API side and it's ready to go. You can get access to the claims principal object and use claims as identifying pieces of information for your user - e.g. identity, roles, other attributes etc.
To get started, look at http://www.asp.net/vnext/overview/authentication/individual-accounts-in-aspnet-web-api
Also as a wrap, I did consider the use of JSON Web Tokens (JWTs) as there is an OWIN library available for generating and parsing these. The use case here would be that you authenticate, get a JWT back, and then use the JWT to get an OAuth 2.0 bearer token. The JWT is useful if you want to move authentication elsewhere, or if you want to get additional information about the user at the MVC side of things.

Resources