Implement IdentityServer 4 and database verification without .NetIdentity - identityserver4

After analyzing all IdentityServer 4 documentation and examples and tutorials, it was not possible to identify how to authenticate a user without having to use AspNetIdentity.
A way is needed to perform verification directly from the database repository without going through .NetIdentity.
Source: https://github.com/IdentityServer/IdentityServer4/tree/main/samples/Quickstarts

Related

How to work with "Identity Management Systems"?

This is my first question, so I hope I don't miss a thing. To be clear from the start: I don't expect an answer which dives deep into detail. This is just about getting a general understanding of how to work with this kind of software.
So I don't know if "Identity Management System" is a suitable term for what I mean but when I talk about Identity Management Systems I think of something like Azure AD, which as far as I know provides e.g. web developers the possibility to integrate a way users can authenticate (including access privilege etc.) on their website.
What I'm quite unsure about is how to work with/ integrate such tools in a project. I will try to make it clear with an example: Assuming I have a website let's say this website is a blog. The blog consist of different posts which are stored in my own database which is connected to the website. The posts are written by different users which authenticate with a tool like Azure AD. The user's data is stored somewhere on a server run by e.g. Microsoft. If I want to display the posts togethere with the name, email.... of the user who wrote them, how would I do this?
Is it possible to query the user's data directly from the Identity Management System and display it? This does not sound ideal to me as the consequence would be that data the website uses is stored in two different locations.
Would you kind of copy the user's data from the Identity Management System to the websites database and query it from there? This does not sound like a good solution either because then data would be duplicated.
So whats the "right workflow"?
I appreciate any hints and further information I can get:-)
AFAIK To get the user's information like name, email etc. you can add these claims while generating the JWT token.
To generate access token, you have multiple authentication flows such as Authorization code flow, ROPC flow, Implicit flow.
To add the claims that you need to return with the token, you can make settings like below:
Go to Azure Portal -> Azure Active Directory -> App Registrations -> Your app -> Token configuration -> Add optional claims
When you decode the token via JSON Web Tokens - jwt.io you can find the user information that you need.
To know how to generate access token, you can refer SO Thread which I solved it before.

How to sync user password between 3 different services when they are hashed in different point of time?

I have 3 microservices that hold particular user information including their sign-in credentials (email + password). If the services are A, B, and C then the user "John" will have his info stored separately in all three of these services' database.
Now, the user info in service A is updated at an earlier point of time, and at that moment it is not predictable whether services B or C will definitely be activated to be used by that particular user. So, there is no point in creating an entry in B and C for "John". But, as "John" activates B or C at a later point of time, the system can only have access to the hashed password.
It is to be noted that the service C requires the password to be stored in encrypted form so that it can be decrypted later. So, merely storing the hashed value in all 3 services is not feasible, neither do we want all 3 of them to have encrypted password.
What is a feasible solution to sync the password between the services by maintaining the requirements?
Your approach implies a lot of problems in addition to the one you already described yourself. I recommend to look into Federated Identity (using OAuth2 and OpenID Connect) which fits for Microservices architectures.
Basically, this means that authentication and credentials handling is performed by a separate highly available and scalable service (usually referred to as identity provider or authorization server) that only does that - handling user credentials, identity and access control - and does it well.
It handles login and issues access tokens which are then sent to your Microservices along with the requests. As each Microservice will trust this identity provider it will be able to verify that the token is valid and was issued by this identity provider (this happens by validating the token with a public key). And the token contains information like user id and information about what actions are allowed with this token.
The identity provider can be a cloud service like Okta, Auth0, Azure AD B2C, etc. (see https://openid.net/developers/certified/#OPServices) or host an identity provider on your own, if you are not able to access cloud services, by using ready-to-use libraries available for your technology stack (https://openid.net/developers/certified/#OPLibs).
So there is no need to store user credentials in each Microservice and sync this information between them. I would consider such an approach as an anti-pattern.
The federated authentication approach also allows to solve other problems such as single-sign-on.
If you are new to that topic it can be a little overwhelming at first but it's something you can't get around if you really want to have all the advantages a Microservices architecture can provide.
This article might help you get started:
https://nordicapis.com/how-to-control-user-identity-within-microservices/

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.

Shibboleth custom password flow

I need to set up Shibboleth IdP to validate user name and password against a custom application.
Our application exposes a REST API to which one can pass a user's credentials and either returns a 401 on failure or a JSON object with some user metadata on success.
I was able to achieve this in SimpleSamlPHP IdP with a 30-line class, but having to switch to Shibboleth, I am having a hard time finding directions to do the same there.
Reading through the documentation the suggested solution seems to be to create a custom back end for the password login flow but the Wiki does not explain in detail how to do this.
Can somebody point me out to some tutorials or sample code on which files need to be created or changed in order to do this (even basic examples of checking against a credential file or database would be fine)?
You are looking for an [External Authentication Flow] (https://wiki.shibboleth.net/confluence/display/IDP30/ExternalAuthnConfiguration)
For an example, see the shib-cas-authn3 project (https://github.com/Unicon/shib-cas-authn3). It uses the CAS Server to authenticate the users. It then creates an IdP session from information retrieved from CAS.

Get input email address from ACS when using LiveID

Is it in any way possible to wire up an ACS rule to return/PassThrough the user's email adress from ACS using $(InputValue) when using Live ID?
I am using Passive authentication and get redirected out to Live ID but I was wondering if there is any way to wire up a rule from ACS that might get the InputValue email address
From what I can see I think this might be possible by hosting a login page of course but I would prefer to be able to get it in some other way from ACS if possible.
(I should have added that the current scenario is to implement Live ID authentication on top of an existing ASP.Net application with a database backend for user identity and roles.)
Extra information related to the current scenario : The current scenario is an EXISTING system with its own home-grown database authentication security model. I tried all sorts of ways to see if I could intercept the user's email address and eventually decided the available approaches for doing this were not desirable (in this specific scenario).
The only suitable and secure pattern found to transition to Live ID authentication in this scenarioo is to build a Registration system around your application which allows an existing user to register their LiveID and then bring them back to your application to capture their Live ID 'nameidentifier'.
However, given that any unknown user could do this it would be necessary to have an interim authentication step via email or some-such mechanism to validate the Live ID email address being used.
I hope this is of help to someone.
Possible but it requires a bit of code for a custom sts:
https://gist.github.com/1867792
Code doesn't build and dependencies aren't included... but it's largely based off an early thinktecture starter site ported to MVC4 with changes shown above.
Unfortunately it is not possible to get any identifiable claims when using ACS with Windows Live. This is due to Windows Live user privacy policy.
With windows live you will only get a ID claim which is unique to your Relying Party application.

Resources