Active directory custom authentication - windows

I had created a sub-authentication package for Windows-7 login. It worked successfully for local account logins.
I then tried to implement same sub-authentication package for active directory in Windows server 2008 r2. I placed my DLLs in Windows\System32\ folder and modified registry values of Kerberos as this Microsoft document explains for sub-authentication dll.
The value I set was in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos Value: Auth0 set to C:\Windows\System32\SubAuth.dll (am I right here?).
But while authenticating I notice that my sub-authentication package doesn't get called as I don't get asked for the second factor while authenticating user on client machine against AD.
Am I missing something in setup or there is something I have to change in my Sub-authentication package.
Let me know if I have missed on any information here.
PS: Sub-authentication package is developed as per the Microsoft's Credential Provider documentations (in Msv1_0SubAuthenticationFilter routine).

Looks like this is by design - Msv1_0SubAuthenticationFilter routine from kerberos\ssv1_0 subauth package will not be called for cached domain interactive logon.
For interactive logon сall chain will be something like:
LsaApLogonUserEx2->MsvSamValidate->MsvpSamValidate->MsvpPasswordValidate
LsaApLogonUserEx2->MsvSamValidate->MsvpSamValidate->Msv1_0SubAuthenticationRoutine
But for cached interactive logon сall chain looks like:
LsaApLogonUserEx2->MsvpPasswordValidate
<and there is no call to Msv1_0SubAuthenticationRoutine here>

To achieve what I have asked in question, I needed to hack around in Microsoft's authentication package.
Here's what I did.
To communicate to active directory & make the authentication w.r.t. AD, I had to do it before hand in credential provider.
So my control flow for the solution goes like this in Credential provider:
Check whether user is connected to network.
If yes, then communicate with AD server, which is predefined & validate user against AD entry.
If user is validated then ask for 2nd factor in credential provider only & then on successful validation, pass user to sub-auth module & bypass 2nd factor in sub-auth.
If user is not connected to network, then validate with sub-auth module.
So basically, I had to first perform 2nd FA if the user needed to validate against AD & perform password authentication later on in the sub-auth module.

Related

How to get the SAM compatible domain name on a Hybrid domain computer?

EDIT:
Thank you #RbMm for your clarification questions!
I am implementing MFA in a credential provider (not a wrapper provider). One of the options I must support is to verify the same UPN is used for logging in to the computer and validating with the MFA provider. I use LsaLogonUser, ImpersonateLoggedOnUser and GetUserNameEx(UserNamePrincipal) to obtain this information. This works in most environments; however, on a computer connected to a hybrid Azure AD domain, LsaLogonUser fails. This lead to an investigation the results of which are elaborated below:
I have a computer belonging to an AzureAD hybrid domain, but I have no way of getting the SAM-compatible domain name from the AzureAD domain name.
For example,
I can log in with a user whose AzureAD upn is, for example's sake user#domain.com. The SAM-compatible name is localdomain\localuser.
GetUserNameEx(NameUserPrincipal) reutrns user#domain.com
GetUserNameEx(NameSamCompatible) returns localdomain\localuser
HOWEVER in the following code, TranslateName fails with GetLastError() returning ERROR_NO_SUCH_DOMAIN.
TCHAR validBuffer[MAX_PATH+1];
ULONG nValidSize = MAX_PATH;
TranslateName("user#domain.com", NameUserPrincipal, NameSamCompatible, validBuffer, &nValidSize);
I have also tried the following APIs without success, they all fail with different return values:
GetComputerObjectName fails with any value passed to NameFormat
GetCompterNameEx fails with ERROR_CANT_ACCESS_DOMAIN_INFO for any relevant value of NameType
NetWkstaGetInfo does not return any useful information in any field
Also, if you look at the computer's join information in This PC > Properties > Advanced System Properties, u see it as part of a workgroup, not a domain.
-if you run the dsregcmd /status command:
executed within the aforementioned user's logon session: the 'Diagnostic' part lists the localdomain in the output
executed from a command prompt running with the LocalSystem account, the output does not list the localdomain anywhere.
An important point (thanks #RbMm) - the code services a Windows Credential Provider, when using the 'Other User' tile. I am trying to pre-verify the entered credentials using LsaLogonUser, before serializing them successfully in my implementation of ICredentialProviderCredential2::GetSerialization. Using 'user#domain.com' fails, while using 'localdomain\user#domain.com' or 'localdomain\localuser' succeeds. When logging in with Windows' built in password provider, using 'user#domain.com' of course works. Maybe I should be using a different authentication package for LsaLogonUser?
I am STUMPED.
thanks for anyone's help..
Uriel

G Suite Martkeplace: Get user who granted domain wide delegation to an app

Assume we have an app on G Suite Marketplace, and a G Suite domain administrator wants to delegate domain-wide access to the domain's users' data (as explained here).
For signup purposes, the 3rd service itself needs to know the domain name and the username of the administrator who performed domain-wide delegation of authority. This is needed to be able to use the Directory API (see note here)
I can easily get the domain name (by using Universal Navigation Extension, and adding ${DOMAIN_NAME} to the callback URL, as explained here). However, I didn't find a way to programmatically access the username of the administrator who performed DWD.
Any hints how to do that? Or if that is possible at all?
Thanks in advance!
Method 1:
When the user clicks in the launcher link (or just during installation with the configuration link you can configure) you need to do the OAuth2 flow and obtain the user email. Then you use the email assuming it is from an admin and it usually should be. If not, just return an error and wait for the admin login.
Method 2: ONLY TO GET THE DOMAIN, not the user.
Use the Marketplace License API https://developers.google.com/gsuite/marketplace/v2/reference
You can periodically use the list endpoint and find the user that installs (or removes) your application.
In any case you should store the list of domain super admins to be used when necessary.

Configure Application Permissions in Azure AD

Background
I have a Web API registered in Azure AD and secured using WindowsAzureActiveDirectoryBearerAuthentication (OAuth2 bearer token). This is a B2B-type scenario where there are no interactive users - the applications calling the API are daemon-like background apps. As such, I don't need any consent experience - I just want trusted applications to be able to call the API, and other applications - even if they present a valid OAuth token - to be denied.
What I've tried
This sample seemed to describe my scenario almost exactly. However, the way it determines if a caller is a trusted app or not is by comparing the clientID presented via a claim by the caller to a hard-coded value. Obviously you could store the list of trusted clientIDs externally instead of hardcoding, but it seems like I should be able to accomplish this via configuration in the AAD portal so that a) I don't have to maintain a list of clientIDs, and b) I don't have to write my own authorization logic.
It seems like I should be able to define a permission for my API, grant that permission to each calling app in AAD (or a one-time admin consent), and then in my API just check for the presence of that permission in the scp claim.
From looking at the portal it seems like this is what Application Permissions are intended for:
I can create a permission just fine via the application manifest. Unfortunately, I can't figure out how to specify that it's an Application Permission, not a Delegated Permission! I tried changing the type from User to Admin as described on MSDN, but that seemed to have no effect.
"oauth2Permissions": [
{
...
"type": "Admin",
...
}
Question
Am I correct that Application Permissions are the best solution for my scenario? If so, how do I configure it? Or, as I fear, is this yet another feature that is On The Roadmap™ but not currently functional?
Ben, Application Permissions are declared in the appRoles section of the manifest. Indeed, if you declare an appRole called say 'trusted' in your resource application's (storage broker demo) manifest - it will show up in the Application Permissions drop down there. Then, when you assign that Application Permission to the client app - the access token that the client app will receive using the client credentials OAuth flow will contain a roles claim with value 'trusted'. Other apps in the tenant will also be able to get an access token for your resource app - but they wont have the 'trusted' roles claim. See this blog post for details: http://www.dushyantgill.com/blog/2014/12/10/roles-based-access-control-in-cloud-applications-using-azure-ad/
Finally, the above way to assign an application permission to a client app only works when both the resource and client application are declared in the same directory - if however these apps are multi-tenant and a customer will install these apps separately - a global admin from customer's directory will need to consent to the client app - which will result in the application permission getting assigned to the instance of client app in the customer's tenant. (my blog post covers this too)
Hope this helps.
ps: if you're stuck - feel free to ping me on the contact page of http://www.dushyantgill.com/blog

Google Admin SDK [Directory - API] check User password

I am using Google Admin SDK Directory API to create users and using Service account I am able to perform CRUD operations on them.
I have a requirement whereby I have to check the credentials of users created using SDK.
When you fetch the users the password is not returned, hence comparison cannot be done.
I'll really appreciate if someone lets me know what would be effective way of approaching the checkCredentials function.
Thanks.
Google does not ever return the value of the password. That would be a monumental security risk.
See their documentation in regards to the user resource used in the directory API. It specifically states that the password field is never returned. It can only be used for setting the password.
If your requirement is too check creds on a newly created user, you should look into trying to login as the user with the password you just sent, using the google auth Apis
At the moment, the only solution I've found is to simulate the user login flow with a fake browser (Apache's httpcomponents-client for Java for example) pointing to Google Account ServiceLogin.

windows azure ACS confirmation for user credentials

I have an application on windows azure where users are authenticating by using ACS ( with ADFS 2.0).
There is a requirement that before certain actions, the user must confirm his identity by retyping his password.
Is there some way to ask ACS to check for credentials when a user is already signed in?
For a moment I thought about checking against the cookies created for the authentication, but I am not really sure that is possible. Besides, this feels just wrong.
Any ideas? I have been trying to search for REST apis of azure's ACS but it seems there are only management api calls for ACS.
There's no way to do this other than signing the user out and making them sign back in again. Even that, though, won't guarantee a password entry in all cases. If ADFS is configured for integrated auth (Kerberos), and the user is on a domain joined machine, they may never have entered their credentials and there's nothing you can do to force them to.

Resources