I am trying to put together some documentation on changes that need to be made to the Database back-end when different actions are performed so they can operate with IdentityServer4, but realizing that I am not sure what items in the database are affected when you perform actions like (adding a new user, adding a new client, and a scope, etc..) I am using this to get a better understanding of how all the elements work together, and how to relate to each other - See below which I am needing to expand on.
Can anyone with good experience with IdentityServer backend help me?
[Adding a new user]
- add a record to dbo.AspNetUsers – All user pertaining information.
- add a record to dbo.AspNetUserClaims – Identifying information stored similar to Key/Value Pair set with a reference pointing to the User
[Adding a new Client – (Controller Web API Endpoint)]
- add a record to dbo.Clients – Details that define the client
- add a record to dbo.ClientGrantTypes – All grant types allowed for authorization to the specified client.
- add a record to dbo.ClientSecrets – Password and secret information pertaining to the client.
- add a record to dbo.ClientScopes – Scope name matched to the ClientId for allowing. You will need to add scope(s) for the client so it can be accessed.
-?? Not sure how IdentityResoure and IdentityClaims are used here, and also how oidc ones are used here.
?? What is the difference between Api and Client in Identity Server DB?
[New Claim type is added, and needs to be included in the data returned with the JWT token]
...
use IdentityServer4.AspNetIdentity for storing users in SQL Server using EF http://docs.identityserver.io/en/release/quickstarts/6_aspnet_identity.html
use IdentityServer4.EntityFramework for storing clients and resources configuration in SQL Server using EF.
http://docs.identityserver.io/en/release/quickstarts/8_entity_framework.html
Look into the samples repository for code samples.
Related
My application is composed of an API layer which is accessable by presenting a Bearer Token, obtained from our Identity Server. Each of our API has a level of scopes that the token must contain in order to be invoked: this means, for example, that if you want to make the API call which "creates a product" you need a write access to products (i.e. the scope "products") while you may just need the scope "products_read" if you only want to retrieve them.
Scopes are bound into the token when you authenticate onto the ID server.
Now, I need this user to be able to perform different operations on different "workspaces". Each workspace administrator can set which permissions each user have. This is, in fact, linked to the scopes that each user will have when operating on that particular workspace.
Right now we have implemented that, if you are trying to access a different workspace, the API layer will check:
if your bearer token is valid (by validating it on the ID server)
if you are authorized to access that workspace
changing associated claims by removing the original "scopes" (set into the token by the ID server) and overwriting with those assigned by the administrator of that workspace
This somehow works, but it stinks because I don't want my application layer (API) to have this kind of responsability and the opportunity to tamper with the token. I want the ID server to handle it and, after the user tries to enter into a different workspace, it generates a new crafted bearer token with correct claims (so the API will just need to trust it).
What's the best approach in doing that? I'm digging into the "custom grant type": may this be the right approach?
Scopes are fixed at design time and the same for all users. I like your use of products and products_read - that is very standard.
When you need dynamic behaviour, implement claims, which depend on who the user is. In your case I would use a workspaces array claim. Since this is a key vaue for authorization, it should be added to access tokens at the time of token issuance. Think in terms of your products scope being composed of claims.
It feels like workspaces and other permissions are part of your business data rather than your identity data. At the time of token issuance, IdentityServer should send identity attributes (eg subject claim) to an API endpoint you provide. which returns business attributes (workspaces). I believe in IdentityServer this is done via a custom profile service.
I'd try to avoid different tokens for different workspaces, since that will be awkward in terms of usability and code complexity. The standard way to do it would be to redirect the user each time.
I've been searching for a similar situation, but don't see one yet. Here's the scenario...
Lets say you have a server that allows multiple people to sign on. There is an application on the server that works with Google Calendar. Anyone can use it.
First, a user must register the service and go through the initial OAuth 2.0 setup. This adds the necessary info (id, token, refresh token, exp time, etc) to a table. Once done, they can use Calendar APIs and in the background the tokens are automatically refreshed.
Now, lets say Bob and Nancy are both set up. What's to stop Nancy from accessing Bob's calendar data as only the ID (ie, bob#gmail.com) is in the Token database and the ID is used to access that specific calendar, but there's no authentication method to USE that actual token record.
Would there be some need to add another layer of authentication to actually accessing a specific record in the Token table? So, before Bob or Nancy can run a addCalendarEvent() type process we'd need to validate it's their ID and not someone else's?
I hope this makes sense. :)
I have a problem with node-oidc-provider.
I want the client list to be stored in the database, but I haven't found a solution.
Please help me!!!
You can have your client definitions stored in a DB, just have your adapter for the Client model respond to the find(id) invocation.
https://github.com/panva/node-oidc-provider/blob/main/docs/README.md#clients
In addition to these clients the provider will use your adapter's find method when a non-static client_id is encountered.
For storing clients in the database, you can make use of below link to store the clients as well as other tokens
https://github.com/panva/node-oidc-provider/blob/main/example/adapters/contributed/sequelize.js
For creating tables, you can use below link
https://github.com/roggervalf/node-oidc-provider/tree/examples/example/migrations/sequelize
I need to add a token inside a token for an "act-as" schema on a custom grant type in IdentityServer3.
I tried with PreserveAccessToken but it just adds the token as a claim in the current ClaimsPrincipal, but can't find a way to nesting it as a claim when getting another token to pass along to the next service/api in the chain.
The idea behind this is for being able to keep an audit of all the hops from the end-user to the last service/api in a chain of calls.
This can be achieved using a custom grant. This allows extending the token endpoint with custom "operations" - e.g. issuing a token that contains delegated claims - e.g. a token.
docs are here: https://identityserver.github.io/Documentation/docsv2/advanced/customGrantTypes.html
here is also a sample that comes close to your scenario: https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source/Multi%20Hop%20Delegation%20(ActAsCustomGrant)
that said - this is probably the most expensive way to convey a user id over multiple hops.
If there is a trusted subsystem between the back-end system, simply transmitting the required data as payload is much simpler and much faster.
I have a restful API that is going to accessed by multiple organizations. Their data is going to always be separate. I am using rails 4.0, emberjs, and phonegap. There are going to multiple devices accessing the API for a single organization at any point in time.
My question is how to properly design my API with these multiple organizations and devices in mind.
Current Solution:
The user must authenticate with the organization name and password. This is done over HTTPS with basic auth. After that the user is given a token that ember stores and is used for each subsequent request. Since there are multiple devices multiple API tokens can be associated with an organization. Rails uses the token to get the organization id with every request so the url /members only outputs the members related to the organization the token belows to. Thoughts on this?
Requiring every restful resource to be started with organization/id/resource seemed insecure and unwieldy to me so that is why I chose my current solution.
A Better Way?
What is a better way of doing this? Should I give each organization a subdomain and pass that back along with the token and use the token only for security and the subdomain for identifying the organization? Or should I just stick with organization/id/resource?
You are right, the token itself should not contain any "organization" part - it's insecure, as well as adding subdomain in the way you've proposed.
Instead of that you can add Organization field to the Token object (or table - depends on how you track tokens). Once you received the token you're able to get the Organization.