Identityserver and SQL server Database - sql-server

we are looking for brand new implementation for Identityserver4,
I wnet thru the documentation and install the Project on VS2017 and DB in sqlserver.
Database is created with the default migration script provided for bot ConfigurationData as well as Operational DAta.
I am very much confused , where the user will be how the clients will be add etc?
Also in the startup the default ASPNEtIdentity is add, but in database there is no ApplicationUser table, so where the userdata will be?
My requirement is simple - User will be aple to login to application by his credentials(or may be by 3rd party application) and will use the application or
API will directly use Identity server to with clientcredential scope,
Here please do let me know:
Should I introduce AspNetIdentity or Not, and Why?
Where is the user table and Password of the user in the database generated by the migration.
How we can add User clients and resources to the Created Database
Do I need to add Login/Logout page ?
In API APIResource is used to defined the Resources "api1" and same is used by the client code to get the access but this "api1" is not used anywhere with the definition/signature of the Method, so ow will it be correlated?

First off, IdentityServer4 on it's own does not handle users or authentication thereof - you either need to use ASP.Net Identity and the integration library that hooks it up to IdentityServer4 or build all of that stuff yourself.
So to sum up:
Yes you'll need to use that or roll your own user store and authentication logic
Either provided by ASP.Net Identity or built yourself
https://www.identityserver.com/documentation/admin-ui/ may fit your needs or you could build your own tooling and/or scripts to do so
Yes although the quickstart samples provide good basic starting points
The bearer token middleware by default will validate the audience (ApiResource.Name) but I prefer to enforce scope at a more granular controller or action level using a filter (e.g. [ScopeAuthorize("my.api")] public MyResult ApiAction() { ... }). This filter will check that the specified scope is defined in the set of claims in the ClaimsPrincipal).

Related

Augment Registration Model

I've been looking at the latest version of identity server with .net core 2.2 and I have a general question about the registration model. At the moment, the default account controller provides pretty much everything I need out of the box. Unfortunately, I have a small requirement to augment the registration model to include a registration code that the user must know in order to register. This could be further augmented with a recaptcha code. Can you override the one individual registration endpoint or would I have to build my own account controller with all the standard endpoints i.e. forgot password, change password etc. endpoints. Also, is there a way to get swagger to output the details about the endpoints that are provided through the identity account controller?
Cheers
Mark

Profile Management with Identity Server

So from what I have read on IdentityServer I should be storing details about the user such as first name and last name inside claims. How would a web application then be able to access the claim information? Since the User Info endpoint requires a valid access token representing the user, I suppose I would need to make an API that could access that returned the profile information of other users? Is this the right way to do it? (use case, web page needs to display contact details that are stored in claims of another user)
Also what would be the way for multiple language profile information be stored and retrieved in the claims? For example a user can have a name/title in multiple languages. I'm thinking of making [LanguageCode]_[ClaimType] (fr_first_name) naming convention and either adding all languages to just the profile IdentityResource or creating separate resources per language.
Your best bet is to set up a project using the IdentityServer4 QuickstartUI example and review that code to better understand how it all works. As of version 4, Identity Server is only focused on the sign-in / sign-out process and the various flows around authentication. They also provide a basic EF-driven persistence model, and they also support the ASP.NET Core Identity persistence model (also EF-driven), but both of those are not meant to be production-ready code.
Basically, persistence of user details is considered your responsibility. That being said, the cookies used for ASP.NET Core authentication greatly restricts how much data you can/should store as claims. The best model is to keep "real" identity provider (IDP) claims as claims, don't add new claims to that list, copy what you need into some other separate user-data table you manage completely, and use the unique claims identifier (almost always "subject id") as the key to your user data. This also makes it easier to migrate a user to another IDP (for example, you'll know user details for "Bob" but he can re-associate his user data away from his Facebook OIDC auth to his Google auth).
Basic persistence isn't too difficult (it's only 12 or 13 SQL statements) but it's a lot more than will fit in a Stackoverflow answer. I blogged about a non-EF approach here -- also not production-ready code (for example, it has ad-hoc SQL to keep things simple), but it should get you started.

Identity Server 4, EF Core, share DbContext between API and IS4

I'm using Identity Server 4, Asp Identity, EF Core and one database.
I have 3 projects at the moment
IdentityServer - Contains all data contexts and all migrations with my app tables
Api - no context, no migrations however I need to access database somehow from here
Clinet - javascript
The question:
How do I access data context from IdentityServer project and still have all settings (db connection, etc) in one place. I understand I can reference IdentityServer from API and use data context but it seems not right to me. What is the preferred way to do this ?
Since you are interested in this option, I've decided to move my comments to this answer.
First of all, IdentityServer is not the place for your app tables. These are seperate contexts and separate migrations. The preferred way is to maintain the separation of concerns.
As I explained in my answer here, you don't need a relation between the login user and your business context. Instead create a user in the business context. The login user has a different purpose than the business user.
I don't have code for you, but you can take one of the sample apps from IdentityServer. Adjust the API to use your business context. In that context add a user table (which links to the sub claim) and the fields you need for the business context. BTW it doesn't matter if the tables are in the same database, just don't mix the contexts.
In IdentityServer: if the user may register for one website then you can extend the registration form with a drop-down of available websites. Or a list if the user can register for multiple websites.
Now it depends on the chosen strategy. You can wait to register the user in the API, but I think it is far more easy to register the user straight away. There are other options, but here's one where it is part of the IdentityServer configuration (without adding business logic to IdentityServer):
Extend IdentityServer to call the API after registering the user. For this I would add a table in the IdentityServer context with URLs to register per website. When the login user is created, call the configured API(s) to register the business user.
In the API you need to add the method that IdentityServer can call to create the user, linked to the sub claim and including the required user information. This way you can suffice with the sub claim to identify the login user and link this to the business user.
You can use a similar strategy for client apps. Extend IdentityServer with an API method to allow client apps to register users.
If you want to withdraw access, you can delete the login user without having to delete the business user. Which you don't want if you don't want to destroy historical information. You can also use claims to specify if the user has access to the website without having to delete the login user.

apex how to login to another application from link in one application?

I have two applications in my workspace, APP 1 and APP 2.
In my case, user will log in to APP 1. from there, i put a menu(or a link) to APP 2. however APP 2 requires authentication. So it will take me to a login page. i would like to eliminate that and get the current user's credentials on APP 1 and login to APP 2.
i'm looking for a simple straightforward method (but need to consider security) to login to APP 2.
what i could think of is apex_collection..i could store credentials n use it to create a login process for APP 2. however apex_collection is session based. eventhough i've set session for APP 2, it still wont read values from my apex_collection.
Does anyone have a suggestion or a solution?
All you need to do is use the same authentication scheme in both applications and set the cookie name attribute to the same value in both authentication schemes like this:
APEX will then use the same session across the two applications and the user will not have to log in again when they navigate from one to the other, provided of course that you pass the SESSION_ID in the URL.
A Few Comments on Default APEX Workspace Authentication Security
It may also be helpful to expand on an explanation of why the solution posted by #TonyAndrews works.
For any Apex Apps within the same workspace, if they use the default "APEX Application Authentication" method, they will consult the same authentication user list... so USER1 and its password is a valid login for any of the "neighboring" applications...
This may be a concern if you are hosting different clients or users that should not be intermingling with the other applications. You can also define user GROUPS in the same place as you set up each workspace user. Each application can have its own security filter that permits access by membership of BOTH user/password authentication AND membership in the appropriate access group.
Sharing workspaces may also be a problem because of the unique user name restriction of a single workspace. You can get around that by:
Defining different name-spaces for each application:
Email addresses are good: "someuser#sampledomain.com"
An app id prefix such as: SHOP_EDNA, SHOP_GARRETT, TC_KAREN, TC_MARLOWE, MY_BORIS etc.
Different name styles: first name only, first name + last initial, etc.
To keep things simple, you can always just spin up a brand new workspace: a warning however is that common user names like `ADMIN` are NOT the same between separate workspaces. There shouldn't be much concern however because apps or workspace users may have the same or different schema access privileges to the database back end.
A Word of Caution to Administrators and Developers:
When you go live with an application or multiple applications on a user-facing system, keep in mind the deployment destination (i.e., the workspace) and what else is sharing that workspace. There are some real situations where apps are not intended to be shared or accessed by other "inside" users. Be sure to read up and understand the security constraints and methods of using Default Apex Authentication security so that it's more than luck that protects your own production/live deployed applications.
I do have the similar requirement, linking from one application page to another.
Tried the above mentioned solution, but still asking to login to second application. My Apex ver is 5.0.3 and trying in same workspace.
Created new authentication schemes for each app with same cookie name and set them as current authentication. Scheme type are Application express accounts.
Setting the link as below from first app page to second.
href="http://servername:port/apex/f?p=224:2:&APP_SESSION"
Could anyone provide a solution, please?
Just an update on this.
I am currently using v21.2 and this is how I do it:
In both applications, go to Shared Components > Authentication Schemes > (Select your Auth Scheme);
Scroll down to Session Sharing and select 'Workspace Sharing';
In one of the applications (source), create a link (as a Navigation Bar List entry, for example) like f?p=173:1:&SESSION., where 173 is the target application ID and 1 is the target page.
After some research, I've found out that this feature (Session Sharing Type) is available since v18 of APEX.

Silverlight Security Concern when Dynamically Setting Connection String with Entity Framework

I am using Entity Framework and have the same model on many databases and servers. I want to set my connection string at runtime based on the logged in user. I am currently overriding CreateObjectContext() in my DomainService and setting the connection string there. This works great, but I'm concerned with the lack of security. For example, in my DomainService, I have an invoke method called SetConnectionString() where I pass in the connections string each time I need a new Entity. This is being done from the DomainContext (client side). Since I am using SQL Integrated Security, I am concerned that someone could manipulate the connection string on the clinet and get access to a database that they are not authorized to use.
What is the most secure way to dynamically set the connection string for the domain entity I want to use at runtime?
I do have the database name and server settings in a database that I could look up from the DomainService if I passed in my project id or some other piece of information, but I am then right back to the same issue - someone could easily spoof this info.
Ideas??
-Scott
Hopefully my answer is relevant as the same security issues are faced by flash developers...
The only way to make this really secure ("this" being database connections from your client side code) is to make each user only have read-only access to their data in the database.
As you are realizing, there is no way to stop the user from monitoring/modifying data that you are sending back to the server. Even if you encrypt the communication, the user still has access to the code and in the case of flash, source code due to trivial decompilation.
I am not a DB developer, but I do security audits of stuff like you are asking often, so the following advice could be wrong, but I just googled, and it seems like maybe you could use views to restrict users (sets of credentials) to specific information.
If not, this article seems relevant to what you want:
http://technet.microsoft.com/en-us/library/cc966395.aspx
What about using the ASP.NET membership framework? Tie the user login with a Login call in the framework to make sure the user an authorized user. Add a "RequiresAuthentication" attribute to each of the functions you want to protect in your domain service.
Here are more details on using ASP.NET membership with Silverlight: WCF RIA Services - Authentication, Roles, and Profiles

Resources