Entra ID Find Bad Authentications Types - chadmcox/Azure_Active_Directory GitHub Wiki
Legacy Authentication
Legacy authentication protocols like POP, IMAP, SMTP, and older Office clients don't support modern security features such as multi-factor authentication (MFA), conditional access, or risk-based policies in Microsoft Entra. These outdated protocols create significant security gaps, making it easier for attackers to exploit credentials through brute-force or phishing attacks. Since they bypass Entra ID Protection signals, legacy authentication is a major vector for compromised sign-ins. Disabling it is a key step in reducing risk and enforcing modern, secure access controls.
Conditional Access Policy: Block legacy authentication with Conditional Access
- Run this in log analytics where the Entra signinlogs and non interactive logs are stored.
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(14d) and ResultType == 0
| extend ClientAppUsed = iff(isempty(ClientAppUsed) == true, "Unknown", ClientAppUsed)
| extend isLegacyAuth = case(ClientAppUsed contains "Browser", "No", ClientAppUsed contains "Mobile Apps and Desktop clients", "No", ClientAppUsed contains "Exchange ActiveSync", "Yes", ClientAppUsed contains "Exchange Online PowerShell","Yes", ClientAppUsed contains "Authenticated SMTP","Yes", ClientAppUsed contains "Unknown", "Unknown", "Yes")
| where isLegacyAuth == "Yes"
| distinct Category,UserDisplayName, UserPrincipalName=tolower(UserPrincipalName), AppDisplayName, ClientAppUsed, isLegacyAuth, UserAgent
| project Category,UserDisplayName, UserPrincipalName=tolower(UserPrincipalName), AppDisplayName, ClientAppUsed, isLegacyAuth, UserAgent
ROPC
ROPC is a legacy authentication flow where users enter their credentials directly into the client app, bypassing modern authentication features like MFA, conditional access, and identity protection signals. Since the password is handled by the app, it increases the risk of credential theft or misuse. ROPC also lacks support for modern security features like device compliance or strong user signals, making it difficult to enforce zero trust principles. Microsoft recommends avoiding ROPC and using interactive, brokered flows instead—especially in security-conscious environments.
- Run this in log analytics where the Entra signinlogs and non interactive logs are stored.
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(14d) and AuthenticationProtocol == 'ropc' and HomeTenantId == ResourceTenantId and ResultType == 0
| distinct AppDisplayName,UPN = tolower(UserPrincipalName),ConditionalAccessStatus,AuthenticationRequirement, ClientAppUsed
| summarize apps=make_list(AppDisplayName) by UPN,ConditionalAccessStatus,AuthenticationRequirement, ClientAppUsed
Device Code
The Device Code flow is designed for devices without browsers (e.g., smart TVs, command-line tools). It prompts users to authenticate on a separate device, which does support MFA and conditional access, unlike ROPC. That makes it more secure than ROPC and legacy auth. However, it has limitations:
- It's not ideal for interactive or high-trust enterprise apps because it doesn't support device compliance or strong identity signals.
- It's user-friendly but less auditable, making governance harder.
- There’s no way to tie the token to the requesting device, so it's not suitable for scenarios where device identity or posture is critical.
Microsoft recommends using interactive flows with broker support (like Authorization Code with PKCE) whenever possible for enterprise and security-sensitive apps.
Conditional Access Policy: Device code flow policies
- Run this in log analytics where the Entra signinlogs and non interactive logs are stored.
let excludeapps = pack_array("Windows Sign In","Microsoft Authenticator App","Microsoft Authentication Broker","Microsoft Account Controls V2","Microsoft Intune Company Portal","Microsoft Mobile Application Management");
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated >= ago(14d) and AppDisplayName !in (excludeapps) and HomeTenantId == ResourceTenantId and ResultType == 0
| where AuthenticationProtocol=="deviceCode"
| project TimeGenerated, UserPrincipalName,ResultType, ResultDescription,UserAgent, IPAddress, Location,AppDisplayName,ResourceDisplayName, AuthenticationProtocol, AuthenticationRequirement