Is it possible to do "on-behalf-of-flow" using OpenIddict? - openiddict

I have a scenario where I have a normal front-facing ASP.net 6 MVC application.
Once the user browses to the application he/she is authenticated using OIDC and the authorization code flow.
Now I want to pass the users access token down to an API for authentication (lets call it API-1). API-1 will do some processing, but API-1 is also dependent of API-2, and API-2 also needs the users identity/credentials.
From what I have read this is called a "on behalf of-flow":
https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/active-directory/azuread-dev/v1-oauth2-on-behalf-of-flow.md
Could such a flow be implemented using OpenIddict? I couldnt find anything in the docs regarding this, and Im fairly new to OIDC and very new to OpenIddict, so I might simply be missing something.

Related

How can I define policies for my API for two types of access tokens, one with an identity (sub) and one without?

I am using IdentityServer4 via ASPNET Core, and I want users to access my API both by the web browser via their identity (Implicit and Hybrid), and by clients programatically (Client Credentials). I realize all I have to do is add AddIdentityServerAuthentication and I am done. However, that only solves the authentication aspect of this problem, not the authorization.
Authorization:
With ASPNET Core, you can just use Role based auth (or PolicyServer permissions which is similar) but only if you have an identity with role claims, that does not work for client credentials. So that brings us to needing to secure by role, or policies AND by scopes. How can I do this?
You cant have multiple policies, if you do, they both must pass.
You can't have multiple auth schemes, because my call to AddIdentityServerAuthentication will have to use the same authority, so how would IdentityServer4.AccessTokenValidation/JwtBearer know which you scheme challenge you are trying to pass?
Multiple requirements could work, but you need to add extra requirements on the condition that you are dealing with a non-identity access token. How can you detect what type of token you are dealing with? Is it safe to just say "If no sub, this is client creds."
Should I scrap this design and force device code flow on my users? Look at az cli it magically opens a browser, and then you can start scripting away to your hearts content. IS4 supports this with ease, especially with verficationUrlComplete
I think I have a working POC, but I am far from happy with it. https://gist.github.com/VictorioBerra/8c333a228c55d86a7c15f7f300284634
It involves basically re-implementing the default scope claim requirement handler and policyservers permission requirement handler. But thats the only way to conditionally apply the requirement handlers based on the token type.
There are at least a couple of ways of how to go around your problem of implementing role based authentication:
You might have misunderstood the fact that a client can have role claims in the client_credentials flow.
You could even have sub claim if you implemented client_credentials_custom flow and essentially bind a client to a particular user account (think of this as a service account)

Look up the user with bearer token with Openiddict Core

I am currently using Openiddict, Identity and Entity Framework to manage my users and assign Bearer tokens to users to protect my API.
My infrastructure is currently using ASP.NET Core Web API in the back end and a separate React application in the front end. The React application makes HTTP calls to my API to retrieve it's data. There is no server side HTML rendering at all in the back end.
Everything works as I need it to for the most part. I can register users and retrieve tokens from the API. These tokens are included in my HTTP call in the Authorization header. My AuthorizationController uses this: https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/AuthorizationController.cs with a few minor tweaks. My Startup.cs also uses almost exactly this https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Startup.cs
In some instances, I need to make API calls to the endpoints that are specific to the user. For instance, if I need to know if a user has voted on a comment or not. Instead of passing along the users ID in a query string to get the user details, I would like to use the Bearer token I received that they use to make the API call for that endpoint. I am not sure how to do this though.
In some research I have done it looks like some samples use ASP.NET Core MVC as opposed to the API to retrieve the user with the User variable as seen here https://github.com/openiddict/openiddict-samples/blob/dev/samples/PasswordFlow/AuthorizationServer/Controllers/ResourceController.cs#L20-L31 however this seems not to apply to my infrastructure.
My question is how do I look up a user based on the Bearer token passed to the API to look up a users details from my database? I am assuming that all of the tokens passed out by the API are assigned to that specific user, right? If that's the case it should be easy to look them up based on the Bearer token.
The question is: How with Openiddict can you look up a user based on the token that was assigned to them for API calls? I need to get the user details before anything else can be done with the application first. Is there something baked internally or do I have to write my own support for this?
When you create an AuthenticationTicket in your authorization controller (which is later used by OpenIddict to generate an access token), you have to add a sub claim that corresponds to the subject/entity represented by the access token.
Assuming you use the user identifier as the sub claim, you can easily extract it from your API endpoints using User.FindFirst(OpenIdConnectConstants.Claims.Subject)?.Value and use it to make your DB lookup.

How to get OAuth 2.0 right for consuming external APIs in my Custom API .net core

I want to create a custom API that behind the scenes, call number of other APIs which use OAuth 2.0 for authentication. I want to manage this internally so that my custom endpoint somewhat abstract this.
Or to begin with I want to do what app like buffer (https://buffer.com) do - where you connect to different social services and than post your status.
How can I achieve this in .NetCore ?? I don't want to login with these (a lot of samples are catering this scenario), user login is different than this. I just want to establish these connections (like API Connections if you look at Azure API Management) and then perform some operations against those endpoints.
I hope i convey my point. please let me know if this isn't clear.
Thanks
Sanjay
OAuth2 systems are all based on the same workflow.
here's an authorization url, you pass some ids in an authorization header, if everything is correct you get a token, you then use the token to do whatever you are allowed to do. What changes are the credentials you use for authentication and the urls you hit for the various parts of this workflow.
You could write your own OAuth2 library which deals with all this, that's pretty much what I did and simply changed the details for every specific system I had to interact with.
This being said you can always use one of the existing implementations to connect to the various systems you care about, they all have an API you could use, all you have to do is make sure you follow the OAuth2 flow correctly.

Are Tokens based on Cookies Restful?

I'm building some RESTful API for my project based on Play Framework 2.X.
My focus is on the authentication mechanism that I implemented.
Currently, I make use of SecureSocial.
The workflow is:
An anonymous user calls a secured API
Server grabs any cookie Id (kind of authentication token) and checks for matching in the Play 2 cache. (cache contains an association between cookie Id (randomly generated) and the user Id, accessible from database.
If any matched, user is authorized to process its expected service.
If none matched, user is redirected to a login page, and when filled with valid credentials (email/password), server stores its corresponding authentication data on Play 2 cache, and sends the newly created Cookie containing only a custom Id (authentication token) to user and of course, secured through SSL.
While the cookie/token doesn't expire, the user can call secured api (of course, if authorized)
The whole works great.
However, after some search, I came across this post, and ...I wonder if I'm in the right way.
Indeed, dealing with cookies ("sessions" in Play's term), would break the rule Restfulness.
Because an api really considered as stateless should be called with ALL the needed data at once (credentials/tokens etc..). The solution I implemented needs both calls: one to authenticate, the other to call the secured API.
I want to make things well, and I wonder some things:
What about the use of Api keys? Should I implement a solution using them instead of this SecureSocial workflow? Api Keys would be sent at EVERY API CALL, in order to keep restfulness.
I think about it since I want my APIs to be reached by some webapps, mobiles and other kind of clients. None of all are forced to manage cookies.
What about OAuth? Should I really need it? Would it replace totally the usage of simple api keys? Always with this objective of several clients, this known protocol would be a great way to manage authentication and authorization.
In one word, should I implement another mechanism in order to be Restful compliant?
this is quite an old Q, but still worth answering as it may interest others.
REST does mandate statelessness, but authorization is a common exception when implementing.
The solution you described requires a single authorization process, followed by numerous service calls based on authorized cookie. This is analog to api keys or OAuth. There's nothing wrong with cookies as long as the service isn't of high-security nature and that you expire then after a reasonable time.
Integrating OAuth into your service sounds a bit of an overkill and is recommended only if you expose the API to 3rd parties (outside your organization).

What's the simplest way to do authentication with a web API?

I've got a web API that provides data to users without authentication (the website lets users post data, after they've logged in using traditional cookies & sessions). Someone wants to develop an iPhone app that adds things to my database, so I want a user to authenticate on the iPhone, and then the api will allow posting.
So, what should I look in to do this easily? The API as it stands is RESTful, it'd be nice to keep it that way. Obviously I'm new to this but there seem to be so many standards I don't know where to start. If I can code it up in less than an hour, that'd be ideal.
Much appreciated!
A decent way to implement this would be to provide the app creator with a token as well as an app id, and have them use that token as salt for an agreed upon encryption method to send username and password (plus app id) to a new API call for a new session.
Upon receiving the request for a new session, you would look up their token based on the appid provided, and try and decrypt the user/pass using the token.
If the user/pass are accepted, then you create a new session and return the session id to them, which they can send along with any new requests.
This prevents the app from having to send authentication for every request, and allows you to expire sessions at a given time.
WebSecurity was introduced in ASP.NET MVC 4. It relies on the SimpleMembershipProvider. It uses FormsAuthentication to manage cookies
WebMatrix.WebData.WebSecurity is provides security and authentication features for ASP.NET Web Pages applications, including the ability to create user accounts, log users in and out, reset or change passwords, and perform related tasks.
You must create or initialize an WebSecurity database before you can use the WebSecurity object in your code.
In the root of your web, create a page (or edit the page ) named _AppStart.cshtml.
_AppStart.cshtml
#{
WebSecurity.InitializeDatabaseConnection("Users", "UserProfile", "UserId", "Email", true);
}
you can authenticate your request by following code.
WebSecurity.Login(LoginName, Password, true)
once authenticated successed , you will get value of WebSecurity.IsAuthenticated is true and you will get user's identity
you can also use "SimpleRoleProvider" for manage roles in your application