How does Active Directory mark a password expired? - active-directory

Our domain has a max password age of 90 days. If I do not change my password for 90 days, what attribute(s) does Active Directory set on my user account to denote that my password has expired?
Is it pwdLastSet = 0?
Does it mark my account as disabled via userAccountControl? Or will it just require me to change my password on next login?
Can I manually mark a password as expired for a specific user account?

That's is correct. It sets the pwdLastSet=0. You can mark the password expired using AuthenticablePrincipal.ExpirePasswordNow() method.
Here's how you can expire password for a single account:
public static void ExpirePwdNow(string username)
{
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "yourdomain.com")
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(ctx, IdentityType.UserPrincipalName, username))
{
if (user != null)
{
user.ExpirePasswordNow();
user.Save();
}
}
}
}
And here's how it looks in AD.
Note* you can do the same thing using PowerShell or VB script. I don't believe there's a way of expiring the password through GUI, but I can't be sure.

Related

How can you check the password complexity policy through the MS Graph Client?

I am successfully adding users to my AD tenant and giving them a role in my application.
User newUser = new User
{
DisplayName = $"{u.GivenName} {u.Surname}",
GivenName = u.GivenName,
JobTitle = u.JobTitle,
Mail = u.Mail,
MobilePhone = u.MobilePhone,
Surname = u.Surname,
AccountEnabled = true,
MailNickname = $"{u.GivenName}{u.Surname.Substring(0, 1)}",
UserPrincipalName = u.Mail,
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = u.Password
}
};
var user = await _graphServiceClient.Users.Request().AddAsync(newUser);
One issue I am running into is that if the password doesn't meet the complexity requirements, the AddAsync() will error out (natch) so I would like to check if the password meets the requirements before attempting to add the new user.
Does anyone know the syntax for this?
Thanks.
There is no method of MS Graph to check your password before adding the user by design. You could use regex to check passwords with complexity requirements as a workaround.
There are some requirements of Azure AD password policies by default:

Connect to Exchange with AD User (Single Sign On)

At the moment I have a Login-Form with Username (logonParamters.Username) and Password (logonParameters.Password) fields.
The code below is working fine but it presupposes that I have a Password to connect to Exchange. But we want to use Single Sign On and if we do so we don't have a Password right? But EWS wants an Username, Password and Domain. So how do I connect to the Exchange using SSO?
var domain = logonParameters.UserName.Split('\\').First();
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
{
// validate the credentials
var username = logonParameters.UserName.Split('\\').Last();
bool isValid = pc.ValidateCredentials(username, logonParameters.Password);
if (!isValid)
{
//throw exception
}
using (UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, username))
{
//Connect to ExchangeWebService with those AD Credentials.
}
}
In the EWS Managed API (or WSDL proxy) you can use the current security context (eg logged on user creds) like
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2016);
service.UseDefaultCredentials = true;
which means getting it to run in a impersonation context and relying on kerberos to do the auth if possible.

Not able to login after create the user in AD using Java

I have written code using JNDI for creating users using DirContext in AD.
After I create the user I am not able to login with those credentials. When I manually reset the password for that user in AD, I am able to login.
Here I have placed my code for your reference,
Hashtable<String, String> ldapenv = new Hashtable<>();
ldapenv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
ldapenv.put(Context.PROVIDER_URL, "ldap://10.95.144.139:389");
ldapenv.put(Context.SECURITY_AUTHENTICATION, "simple");
ldapenv.put(Context.SECURITY_PRINCIPAL, "CN=Administrator,CN=Users,dc=Merck,dc=local");
ldapenv.put(Context.SECURITY_CREDENTIALS, "Merck2017");
DirContext context = new InitialDirContext(ldapenv);
Attributes attributes = new BasicAttributes();
// Create the objectclass to add
Attribute objClasses = new BasicAttribute("objectClass");
objClasses.add("top");
objClasses.add("person");
objClasses.add("organizationalPerson");
objClasses.add("user");
// Assign the username, first name, and last name
String cnValue = new StringBuffer(user.getFirstName()).append(" ").append(user.getLastName()).toString();
Attribute cn = new BasicAttribute("cn", cnValue);
Attribute sAMAccountName = new BasicAttribute("sAMAccountName", user.getUserName());
Attribute principalName = new BasicAttribute("userPrincipalName", user.getUserName()
+ "#" + "merck.local");
Attribute givenName = new BasicAttribute("givenName", user.getFirstName());
Attribute sn = new BasicAttribute("sn", user.getLastName());
Attribute uid = new BasicAttribute("uid", user.getUserName());
// Add password
Attribute userPassword = new BasicAttribute("userPassword", user.getPassword());
Attribute pwdAge = new BasicAttribute("pwdLastSet","-1");
Attribute userAccountControl = new BasicAttribute("userAccountControl", "544");
// Add these to the container
attributes.put(objClasses);
attributes.put(sAMAccountName);
attributes.put(principalName);
attributes.put(cn);
attributes.put(sn);
attributes.put(givenName);
attributes.put(uid);
attributes.put(userPassword);
attributes.put(userAccountControl);
attributes.put(pwdAge);
// Create the entry
try {
context.createSubcontext(getUserDN(cnValue,"Merck-Users"), attributes);
System.out.println("success === ");
} catch (Exception e) {
System.out.println("Error --- "+e.getMessage());
}
Please help me resolve the following issues:
How do I set AD user password while creating the user using the above code?
How do I set userAccountControl to 66048 in the above code?
How do I create the user enabled while using the above code?
How do I disable the option "user must change the password in next login" while creating the user in the above code?
Thanks in advance.
I don't have all the answers, but this should get you started:
Passwords can only be set over a secure channel, like LDAPS (LDAP over SSL). Since you are connecting to port 389, that is not SSL and AD won't let you set the password. You must connect to the LDAPS port: 636. You may run into issues trusting the SSL certificate. I can't help much here since I'm not a Java developer, but there is an example here.
The answer to your second and third questions is the same: Accounts with no passwords are always disabled. Since you haven't set the password properly, the account will be disabled. Once you figure out how to set the password, you can also set userAccountControl to whatever you need.
You are disabling the "user must change password" option correctly: by setting pwdLastSet to -1. That's the right way to do it. But you may have to fix the other issues first.
Another important thing: I have created AD accounts in .NET, and I have found that I had to create the account first, then go back and set the password and set the userAccountControl attribute after. You may have to do the same.

Azure AD B2C - Recover your Account differs from Reset Password

I am using Azure AD B2C (and MSAL), and have sign up / sign in, edit profile and password reset policies enabled and working.
However, I have noticed an anomaly if you are going through the Edit Profile workflow and select Recover Account, the flow returned is not the same as the Reset Password policy linked to the login flow.
When the user enters identity info and the captcha, it returns the error 'your organisation has not set up a password reset policy', even though I have as it works if you choose it on sign in.
This is how I set password reset
AuthenticationResult authResult = await ADB2CClient.AcquireTokenAsync(Scopes, GetUserByPolicy(accounts, EditProfilePolicy), UIBehavior.NoPrompt, string.Empty, null, AuthorityEditProfile, App.UiParent);
This is how I set Edit Profile
authenticationResult = await ADB2CClient.AcquireTokenAsync(Scopes, firstAccount, UIBehavior.SelectAccount, string.Empty, null, AuthorityResetPassword, App.UiParent);
However, as mentioned the Recover your Account option on Edit Profile clearly triggers a different flow and I'm unclear how to account for that in Policies?
I guess you are passing different policy names when you are getting authenticationResult. For example, In case of password reset policy, you are passing "AuthorityEditProfile" to get the authentciationResult and in case of edit profile, you are passing "AuthorityResetPassword".
Could you change it and try it again.
For edit profile:
AuthenticationResult authResult = await ADB2CClient.AcquireTokenAsync(Scopes, GetUserByPolicy(accounts, EditProfilePolicy), UIBehavior.NoPrompt, string.Empty, null, AuthorityEditProfile, App.UiParent);
For password reset:
authenticationResult = await ADB2CClient.AcquireTokenAsync(Scopes, firstAccount, UIBehavior.SelectAccount, string.Empty, null, AuthorityResetPassword, App.UiParent);

Is user has active session on IDMsrv?

How to verify IDM does it have an active session for the user signing in?
details - If user'A' has a active session on IDM from browser 'X', When the same user 'A' try to login using browser 'Y', expected behavior identify that user has active session and invalidate the browser'X' session.
Background-
IDM with aspnetIdentity
Client with Implicit grant
(30 sec identitytoken life, does kept renewing access token silently without going to login page, expected to hit some method on the IDM then I can verify user has access or not)!!
Brock has already mentioned about it, It should be at the time of login and logout
It make sense,why its not in Idm. but its definitely possible to provide this as an enhanced feature at least in the coming versions.
Profile Service, IsActive method is the one hit by authorize and
tokenvalidation end point.
so at the time of login persist session, then when the above code hits do the check as per business requirement.
as long as the session is active ( cookie life time) the silent authentication will be passed with the application logic. so this can be controlled by cookie lifetime as well.
public override async Task IsActiveAsync(IsActiveContext context)
{
var sub = context.Subject.GetSubjectId();
var user = await userManager.FindByIdAsync(sub);
//Check existing sessions
if (context.Caller.Equals("AccessTokenValidation", StringComparison.OrdinalIgnoreCase))
{
if (user != null)
context.IsActive = !appuser.VerifyRenewToken(sub, context.Client.ClientId);
else
context.IsActive = false;
}
else
context.IsActive = user != null;
}
signin
public async Task<IActionResult> Login(LoginInputModel model)
{
if (ModelState.IsValid)
{
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberLogin, false);
if (result.Succeeded)
{
//Update security stamp to invalidate existing sessions
//TODO: This didn't invalidate the existing cookie from another client
//var test= _userManager.UpdateSecurityStampAsync(_userManager.FindByEmailAsync(model.Email).Result).Result;
appUser.PersistSession(new UserSession
{
CreatedOn = DateTimeOffset.Now,
DeviceUniqueId = GetDeviceId(),
UserId = _userManager.FindByNameAsync(model.Email).Result.Id,
SId = httpContext.HttpContext.Session.Id,
ClientId= httpContext.HttpContext.Request.QueryString.Value.GetClientIdFromQuery(),
ExpiresOn = DateTimeOffset.Now.AddMinutes(appSettings.SessionTimeOut)
});
_logger.LogInformation(1, "User logged in.");
return RedirectToLocal(model.ReturnUrl);
}
This method has a few drawback when IIS gets restarted and if user has not signed out properly.
there may be a better options this is not the best fit.!
Update:
refer here duplicate/similar question
idmsrv endpoints are missing security change check
Issue raised
Should be like this #tibold

Resources