ADFS not issuing claims from custom attribute stores to some users - active-directory

I'm trying to work out why some of our users aren't issued claims by our custom attribute stores.
Our main attribute store for authentication is Active Directory, but we are using two custom attribute stores to issue several custom claims to users, and also to perform some logging of claims issued. When an affected user logs in, they are authenticated successfully by AD, but have no more claims added. According to the logging in our attribute stores, the BeginExecuteQuery is never called.
I can't see anything to link the affected users, but they mainly seem to be new users, or users that have not logged into the system in a long time. Restarting ADFS sometimes clears the problem, but whether it does or not seems to be random.
I'm trying to understand why an attribute store would be ignored by ADFS on logon for certain users, when it works fine for others. If there is a quick guaranteed temporary fix to get users' claims issued correctly, that would be useful too!
For security reasons, I don't have access to the ADFS Debug tracing.

This was eventually solved with a longs string of calls to Microsoft's AD FS support team. The problem was traced to a piece of our claims rule language which was using the lastLogon and lastLogonTimestamp AD attributes without understanding how they actually behaved. This meant that for some users the condition to grant the custom claims was never met.

Related

Use Microsoft OAuth to authenticate our own operations

We have built a React web application that authenticates users with Microsoft via OAuth ( #azure/msal-browser package). Users are redirected to Microsoft auth page during signin, and then redirected back to our site once authentication has completed successfully. This is all working as expected.
However, we are in a position where we wish to add a custom PIN mechanism to protect some of our workflows. PINs will be encrypted/salted and stored in our own API, along with the existing mapping between Microsoft/Azure users and our own user state/records. In order for users to change/reset their PIN, we want to force them to reauthenticate with Microsoft before changing their PIN. I have not dealt with OAuth2 in a while, and am not entirely certain how this might be possible (since current auth workflow does not involve our server at all).
Ideally, users would navigate to the "Reset PIN" page and initiate the workflow. If possible, authentication would be handled through a pop-up (so as to not lose page state), which I think is possible as per documentation? If this is not possible, even a redirect to the same page with a specific query parameter (to indicate post-authentication) could work. The user would then be able to change/confirm their new PIN. At this point, a request would be sent to our API, including both the PIN and something from Microsoft that would allow our server to validate that the user did indeed just re-authenticate (proving they can change the PIN).
The primary sticking point is that our API must be able to verify that the user has just re-authenticated with Microsoft! One way to think about it would be that if a user gained temporary access to an unlocked authenticated workstation, they should not be able to perform restricted actions (as they do not know the PIN), nor be able to change the PIN (as they do not know the user's credentials). Yes, yes, I know physical access is effectively a compromise to any security, but this is a higher-level requirement...
I am guessing this workflow is possible, but am not certain how it might be possible. Would we use a different authentication workflow for this particular use case? Any pointers on a workflow we could investigate or use for this?
I can give you some info about how this should work. This type of flow can require a high level of extensibility in the authorization server though.
CLIENT REDIRECT
The client can send the OpenID Connect acr_values parameter, indicating the assurance levels it requires. In your case you would send two values.
CUSTOM AUTHENTICATION FACTOR
The user will perform standard authentication first, eg passwords. Then you would implement a custom second factor that uses the user identity and some custom logic to call your custom API.
ACCESS TOKENS
After authentication has completed, the authorization server will issue access tokens to the client. High privilege claims should only be included when strong authentication has been used. Some kind of scripting would be used here, that can read authentication result attributes.
API AUTHORIZATION
APIs should receive short lived access tokens. If it contains the high privilege claim, you know that your PIN requirements have been met.
CAN YOU SIMPLIFY?
It feels suspect to do your own PIN management. Can you outsource this, eg use a second factor of time based one time password (TOTP) instead? Mobile platforms such as the Google authenticator app provide tested solutions.

Best practices for similar RBAC schemas?

I all, I'm writing a boilerplate for future projects. Composition is as follows:
Server:
Express,
Prisma 2,
Typescript,
JWT Auth (Access token in memory, Refresh in cookie)
MySQL
I'm writing an RBAC schema, and have successfully written express middlewares to determine if a user is logged in, and for if a user has a specific permission on their role.
If you've ever used any of the minecraft server permission plugins, I'm trying to emulate the common pattern used there.
Users have role(s)
Roles have permissions
Roles can inherit permissions from one or more roles
Roles have a "nextRole" field to determine what role to give when the "promote" event is triggered.
Everything works fine on the server side.
What I'm wondering about is, how should I go about copying the middlewares (login, permissions) to the client side, and how should I determine whether a user has permission to do something?
What I've looked at:
Creating a "hasPermission" endpoint wouldn't be very good as I'd need to make an API call every time a permission check is needed.
Eager loading all roles and permissions from the api when logging in and returning them in the response (I can't eager load the recursive role inheritance/nextRole as far as I know)
Returning ONLY the user without roles and permissions for the JWT/login bit and getting roles/permissions from their own endpoints (again, needs to be recursive to get all inheritance and said permissions from inheritance)
Has anyone created an RBAC schema like this, and how did you go about checking permissions on the client side without being too redundant/using too much memory/too many api calls?
This is a good question, here's my answer to it.
An app is normally protected by the auth info, which means it could be blocked if a user is not permitted. If this is a server application, it can be easily done, because the session can be used to find out the current user info including roles.
However if this is a client app, it's a bit tricky. Say we can protect a route (page or section of page) once the user log in.
if (!user.authenticated) return null
We can use the above line to block private or public user. Or other information you can grab from the user to protect more.
if (user.role !== 'Admin') return null
We could wrap in these into a component, such as
<Allow role="admin" render={...} />
I believe you get the point. However there's something which is very unique about the client approach. The entire user info is returned back, and only the user info, not the user type or permission type.
So to follow your plan, do we need to share a permission or role type to the client side? This is a million dollar question.
In practice, the UI never needs the complete info, why? because UI normally reshapes the permission a bit. That doesn't mean you can't share the complete info from the backend. Doing that may make the UI job easy or more complicated. Nobody knows.
The reason is what I explained above, the UI is writing a if statement (could be hidden) anyway. Either this if is true or false, most of the front-end code is already loaded. It's very different than the backend version, which can entirely block the deliver of the content.

Authenticate web app as another user for support purposes using OAuth and/or Auth0

Is there any way to allow certain users (perhaps with an admin role and appropriate permissions) to authenticate a React app as another user?
The use case would be to allow support staff to authenitcate as another user to see the app as they see it, and debug or help users with their issues.
Thanks!
It's a good question and a common requirement, but unfortunately can be difficult to implement. Ultimately though this type of solution always involves claims and work in APIs.
OAUTH STANDARDS
It is worth keeping an eye on evolving standards such as the On Behalf Of Flow, to see if they can help. However, they may not meet your requirements or be supported by your vendor yet.
AUTHENTICATION
A support user 'signing in as a business user' is not really right, since users always sign in with their own credentials. In the normal case this may need to an access token containing these claims and a user could only make order changes if their token contains this scope:
subject: businessUser1
role: customer
scope: openid orders
IMPERSONATION
In the impersonation case the support person would sign in with their own credentials and may then receive an access token with these claims. You could perhaps use these claims to only allow certain actions to be performed by support users:
subject: supportUser1
role: support
can_impersonate: true
scope: openid orders
Ideally it would be good to prompt users with the 'can_impersonate' claim at the time of authentication / token issuance. This would involve popping up a screen where the business user could be entered, then included in access tokens and also audited.
EXTENSIBILITY
Typically though this would require a custom authentication action, which is often needed for more advanced authentication cases. If this is not supported by your provider then you may need to do more work in your apps, such as:
Invoking a screen after login completes
Storing the business user in your API data
Perhaps also auditing the impersonation event in your API data
2022 UPDATE
Recently at Curity we have published some detailed articles on impersonation. Anyone wanting to implement this pattern might find them useful:
Aproaches
Tutorial

Delegate and impersonate as a user with admin/app credentials

One thing I do currently in an enterprise app is logon to a single admin email account that has delegation over other users and using delegation, we are able to manipulate email/calendar/contacts of users.
I'm looking to use the Microsoft Graph API and I have managed to use admin delegation and gain access to various resources, however last modified (on Onedrive/Sharepoint) is showing the app instead of an individual user.
I understand I can use Oauth and logon as individual users, capture a token and then do what I need under the context of that user, but, I need to do this server side where tasks run. Is there anyway to use admin approved delegation/impersonation from the app so that the users don't have to signin?
e.g. standard that works:
https://graph.microsoft.com/v1.0/sites/my-site.office.com/drive/root:/file.txt:/content
Looking to add a user tag, but this doesn't work:
https://graph.microsoft.com/v1.0/user/{id-of-user}/sites/my-site.office.com/drive/root:/file.txt:/content`
After searching for ages, the closest I have read seems to be in here however, I was wondering if there was a standard way of doing this - I haven't been able to get the JWT part of this working (and not sure if this is even the correct thing I am looking for).

In Dynamics CRM, how much of a non null, predictable-format identifier is really "domainname"?

I have code that calls the Dynamics CRM Web API to get information about a Dynamics user. It doesn't know the user's internal Dynamics identifier ahead of time and thus relies on their Active Directory login as a key in queries.
I have a few doubts and questions about that :
domainname (i.e. user login) is a mandatory field when you create a user in Dynamics, but will it always be non-empty - even when you disable the user for instance?
I noticed that you can indifferently specify a login in the form domain\username and username#fulldomainname at user creation. Login seems to be kept intact inside Dynamics, so when you use the API you must be aware of the format it was entered in in the first place. For instance, searching for mydomain\bob won't give you a bob#mydomain user.
Are there any other possible formats for a user's login in Dynamics CRM or are we safe assuming that it will follow one of these 2 patterns?
Is domainname case-sensitive?
How do Dynamics modules or third party tools that somehow only have windows logins to start with manage to find users deterministically? For instance, we could have an external application that needs to access all the Leads owned by a particular user in Dynamics. Do they systematically try all different login formats and all combinations of cases? I think it would be pretty spooky.
The attribute domainname will not be emptied on disabling the user - this will only affect the state of the record.
It's true that you have to consider both variants if your authentication authority allows both variants (see last point) when using domainname as a query criteria.
I could not think of a real world 3rd variation that allows omitting the domain name.
The domain name is not case-sensitive.
Since there are basically 2 (real world) options for on-premise systems, it's not that spooky after all: You can either authenticate against IIS directly or SSO via STS/ADFS. Both impose the accepted login and use common windows authentication methods.
There's nothing special CRM needs to handle - it relies on users arriving with a valid authentication token.

Resources