1301 lines
51 KiB
C#
1301 lines
51 KiB
C#
/*
|
|
Copyright 2021 VMware, Inc.
|
|
SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Selectors;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.InteropServices.WindowsRuntime;
|
|
using System.Security;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Channels;
|
|
using System.ServiceModel.Security;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using VMware.Binding.WsTrust;
|
|
using VMware.Binding.WsTrust.SecurityContext;
|
|
using VMware.vSphere.LsClient;
|
|
using VMware.vSphere.SsoAdminClient.DataTypes;
|
|
using VMware.vSphere.SsoAdminClient.SsoAdminServiceReference2;
|
|
|
|
namespace VMware.vSphere.SsoAdminClient
|
|
{
|
|
public class SsoAdminClient
|
|
{
|
|
private const int WEB_OPERATION_TIMEOUT_SECONDS = 30;
|
|
|
|
private SsoPortTypeClient _ssoAdminBindingClient;
|
|
private UserPassSecurityContext _securityContext;
|
|
|
|
public SsoAdminClient(string hostname, string user, SecureString password, X509CertificateValidator serverCertificateValidator)
|
|
{
|
|
if (hostname == null) throw new ArgumentNullException(nameof(hostname));
|
|
if (user == null) throw new ArgumentNullException(nameof(user));
|
|
if (password == null) throw new ArgumentNullException(nameof(password));
|
|
|
|
var lsClient = new LookupServiceClient(hostname, serverCertificateValidator);
|
|
|
|
// Create STS Client
|
|
var stsUri = lsClient.GetStsEndpointUri();
|
|
_securityContext = new UserPassSecurityContext(user, password, stsUri, serverCertificateValidator);
|
|
// Initialize security context with Saml token by username and password
|
|
_securityContext.GetToken();
|
|
|
|
// Create SSO Admin Binding Client
|
|
var ssoAdminUri = lsClient.GetSsoAdminEndpointUri();
|
|
ServiceUri = ssoAdminUri;
|
|
User = user;
|
|
_ssoAdminBindingClient = new SsoPortTypeClient(GetBinding(), new EndpointAddress(ssoAdminUri));
|
|
_ssoAdminBindingClient.ChannelFactory.Endpoint.EndpointBehaviors.Add(new WsTrustBehavior());
|
|
|
|
var serverAuthentication = GetServerAuthentication(serverCertificateValidator);
|
|
|
|
if (serverAuthentication != null)
|
|
{
|
|
_ssoAdminBindingClient
|
|
.ChannelFactory
|
|
.Credentials
|
|
.ServiceCertificate
|
|
.SslCertificateAuthentication = serverAuthentication;
|
|
}
|
|
}
|
|
|
|
#region Private Helpers
|
|
private X509ServiceCertificateAuthentication GetServerAuthentication(X509CertificateValidator serverCertificateValidator)
|
|
{
|
|
if (serverCertificateValidator != null)
|
|
{
|
|
return new X509ServiceCertificateAuthentication
|
|
{
|
|
CertificateValidationMode = X509CertificateValidationMode.Custom,
|
|
CustomCertificateValidator = serverCertificateValidator
|
|
};
|
|
}
|
|
|
|
// Default .NET behavior for TLS certificate validation
|
|
return null;
|
|
}
|
|
|
|
private static MessageEncodingBindingElement GetWcfEncoding()
|
|
{
|
|
// VMware STS requires SOAP version 1.1
|
|
return new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);
|
|
}
|
|
|
|
private static HttpsTransportBindingElement GetWcfTransport(bool useSystemProxy)
|
|
{
|
|
// Communication with the STS is over https
|
|
HttpsTransportBindingElement transport = new HttpsTransportBindingElement
|
|
{
|
|
RequireClientCertificate = false
|
|
};
|
|
|
|
transport.UseDefaultWebProxy = useSystemProxy;
|
|
transport.MaxBufferSize = 2147483647;
|
|
transport.MaxReceivedMessageSize = 2147483647;
|
|
|
|
return transport;
|
|
}
|
|
|
|
private static CustomBinding GetBinding()
|
|
{
|
|
|
|
// There is no build-in WCF binding capable of communicating
|
|
// with VMware STS, so we create a plain custom one.
|
|
// This binding does not provide support for WS-Trust,
|
|
// that support is currently implemented as a WCF endpoint behaviour.
|
|
var binding = new CustomBinding(GetWcfEncoding(), GetWcfTransport(true));
|
|
|
|
var timeout = TimeSpan.FromSeconds(WEB_OPERATION_TIMEOUT_SECONDS);
|
|
binding.CloseTimeout = timeout;
|
|
binding.OpenTimeout = timeout;
|
|
binding.ReceiveTimeout = timeout;
|
|
binding.SendTimeout = timeout;
|
|
|
|
return binding;
|
|
}
|
|
|
|
private WsSecurityContext CreateAuthorizedInvocationContext()
|
|
{
|
|
// Issue Bearer token to authorize create solution user to SSO Admin service
|
|
var bearerToken = _securityContext.GetToken();
|
|
|
|
// Set WS Trust Header Serialization with issued bearer SAML token
|
|
var securityContext = new WsSecurityContext
|
|
{
|
|
ClientChannel = _ssoAdminBindingClient.InnerChannel,
|
|
Properties = {
|
|
Credentials = {
|
|
BearerToken = bearerToken
|
|
}
|
|
}
|
|
};
|
|
return securityContext;
|
|
}
|
|
|
|
String SecureStringToString(SecureString value)
|
|
{
|
|
IntPtr valuePtr = IntPtr.Zero;
|
|
try
|
|
{
|
|
valuePtr = Marshal.SecureStringToGlobalAllocUnicode(value);
|
|
return Marshal.PtrToStringUni(valuePtr);
|
|
}
|
|
finally
|
|
{
|
|
Marshal.ZeroFreeGlobalAllocUnicode(valuePtr);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Public interface
|
|
|
|
public Uri ServiceUri { get; }
|
|
public string User { get; }
|
|
|
|
public PersonUser CreateLocalUser(
|
|
string userName,
|
|
string password,
|
|
string description = null,
|
|
string emailAddress = null,
|
|
string firstName = null,
|
|
string lastName = null)
|
|
{
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin CreateLocalSolutionUser operation
|
|
var ssoPrincipalId = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.CreateLocalPersonUserAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
userName,
|
|
new SsoAdminPersonDetails
|
|
{
|
|
description = description,
|
|
emailAddress = emailAddress,
|
|
firstName = firstName,
|
|
lastName = lastName
|
|
},
|
|
password)).Result;
|
|
|
|
return GetLocalUsers(ssoPrincipalId.name, ssoPrincipalId.domain, authorizedInvocationContext);
|
|
}
|
|
|
|
private PersonUser GetLocalUsers(string userName, string domain, WsSecurityContext wsSecurityContext)
|
|
{
|
|
// Invoke SSO Admin FindPersonUserAsync operation
|
|
var personUser = wsSecurityContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindPersonUserAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = userName,
|
|
domain = domain
|
|
})).Result;
|
|
|
|
Nullable<int> passwordRemainingDays = null;
|
|
try {
|
|
passwordRemainingDays = wsSecurityContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetDaysRemainingUntilPasswordExpirationAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = userName,
|
|
domain = domain
|
|
})).Result;
|
|
} catch {}
|
|
|
|
|
|
return new PersonUser(this)
|
|
{
|
|
Name = personUser.id.name,
|
|
Domain = personUser.id.domain,
|
|
Description = personUser.details.description,
|
|
FirstName = personUser.details.firstName,
|
|
LastName = personUser.details.lastName,
|
|
EmailAddress = personUser.details.emailAddress,
|
|
Locked = personUser.locked,
|
|
Disabled = personUser.disabled,
|
|
PasswordExpirationRemainingDays = passwordRemainingDays
|
|
};
|
|
}
|
|
|
|
public IEnumerable<PersonUser> GetLocalUsers(string searchString, string domain)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin FindPersonUsersAsync operation
|
|
var personUsers = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindPersonUsersAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoAdminPrincipalDiscoveryServiceSearchCriteria
|
|
{
|
|
searchString = searchString,
|
|
domain = domain
|
|
},
|
|
int.MaxValue)).Result.returnval;
|
|
|
|
if (personUsers != null)
|
|
{
|
|
foreach (var personUser in personUsers)
|
|
{
|
|
Nullable<int> passwordRemainingDays = null;
|
|
try {
|
|
passwordRemainingDays = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetDaysRemainingUntilPasswordExpirationAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
personUser.id)).Result;
|
|
} catch {}
|
|
yield return new PersonUser(this)
|
|
{
|
|
Name = personUser.id.name,
|
|
Domain = personUser.id.domain,
|
|
Description = personUser.details.description,
|
|
FirstName = personUser.details.firstName,
|
|
LastName = personUser.details.lastName,
|
|
EmailAddress = personUser.details.emailAddress,
|
|
Locked = personUser.locked,
|
|
Disabled = personUser.disabled,
|
|
PasswordExpirationRemainingDays = passwordRemainingDays
|
|
};
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public IEnumerable<PersonUser> GetPersonUsersInGroup(string searchString, DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin FindPersonUsersAsync operation
|
|
var personUsers = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindPersonUsersInGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = group.Name,
|
|
domain = group.Domain
|
|
},
|
|
searchString,
|
|
int.MaxValue)).Result.returnval;
|
|
|
|
if (personUsers != null)
|
|
{
|
|
foreach (var personUser in personUsers)
|
|
{
|
|
Nullable<int> passwordRemainingDays = null;
|
|
try
|
|
{
|
|
passwordRemainingDays = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetDaysRemainingUntilPasswordExpirationAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
personUser.id)).Result;
|
|
} catch {}
|
|
yield return new PersonUser(this)
|
|
{
|
|
Name = personUser.id.name,
|
|
Domain = personUser.id.domain,
|
|
Description = personUser.details.description,
|
|
FirstName = personUser.details.firstName,
|
|
LastName = personUser.details.lastName,
|
|
EmailAddress = personUser.details.emailAddress,
|
|
Locked = personUser.locked,
|
|
Disabled = personUser.disabled,
|
|
PasswordExpirationRemainingDays = passwordRemainingDays
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DeleteLocalUser(
|
|
PersonUser principal)
|
|
{
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin DeleteLocalPrincipal operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.DeleteLocalPrincipalAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
principal.Name));
|
|
}
|
|
|
|
private DataTypes.Group FindGroup(string name, string domain, WsSecurityContext wsSecurityContext)
|
|
{
|
|
// Invoke SSO Admin FindGroupAsync operation
|
|
var group = wsSecurityContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = name,
|
|
domain = domain
|
|
})).Result;
|
|
|
|
return new DataTypes.Group(this)
|
|
{
|
|
Name = group.id.name,
|
|
Domain = group.id.domain,
|
|
Description = group.details.description
|
|
};
|
|
}
|
|
|
|
public IEnumerable<DataTypes.Group> GetGroupsInGroup(string searchString, DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin FindGroupsInGroupResponse operation
|
|
var groups = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindGroupsInGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = group.Name,
|
|
domain = group.Domain
|
|
},
|
|
searchString,
|
|
int.MaxValue)).Result.returnval;
|
|
|
|
if (groups != null)
|
|
{
|
|
foreach (var g in groups)
|
|
{
|
|
yield return new DataTypes.Group(this)
|
|
{
|
|
Name = g.id.name,
|
|
Domain = g.id.domain,
|
|
Description = g.details.description
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
public DataTypes.Group CreateLocalGroup(string name, string description)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin FindGroupsAsync operation
|
|
var ssoAdminGroup = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.CreateLocalGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
name,
|
|
new SsoAdminGroupDetails
|
|
{
|
|
description = description
|
|
})).Result;
|
|
|
|
if (ssoAdminGroup != null)
|
|
{
|
|
return FindGroup(ssoAdminGroup.name, ssoAdminGroup.domain, authorizedInvocationContext);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public DataTypes.Group UpdateLocalGroup(DataTypes.Group group, string description)
|
|
{
|
|
if (description == null) {
|
|
description = string.Empty;
|
|
}
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin DeleteLocalPrincipal operation
|
|
var updatedGroup = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.UpdateLocalGroupDetailsAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
group.Name,
|
|
new SsoAdminGroupDetails
|
|
{
|
|
description = description
|
|
})).Result;
|
|
|
|
if (updatedGroup != null)
|
|
{
|
|
return FindGroup(updatedGroup.name, updatedGroup.domain, authorizedInvocationContext);
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
public void RemoveLocalGroup(DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin DeleteLocalPrincipal operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.DeleteLocalPrincipalAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
group.Name));
|
|
}
|
|
|
|
public IEnumerable<DataTypes.Group> GetGroups(string searchString, string domain)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin FindGroupsAsync operation
|
|
var ssoAdminGroups = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.FindGroupsAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalDiscoveryService",
|
|
Value = "principalDiscoveryService"
|
|
},
|
|
new SsoAdminPrincipalDiscoveryServiceSearchCriteria
|
|
{
|
|
searchString = searchString,
|
|
domain = domain
|
|
},
|
|
int.MaxValue)).Result.returnval;
|
|
|
|
if (ssoAdminGroups != null)
|
|
{
|
|
foreach (var group in ssoAdminGroups)
|
|
{
|
|
yield return FindGroup(group.id.name, group.id.domain, authorizedInvocationContext);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool AddPersonUserToGroup(PersonUser user, DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin AddUserToLocalGroupAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.AddUserToLocalGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = user.Name,
|
|
domain = user.Domain
|
|
},
|
|
group.Name)).Result;
|
|
}
|
|
|
|
public bool AddGroupToGroup(DataTypes.Group groupToAdd, DataTypes.Group destinationGroup)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin AddGroupToLocalGroupAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.AddGroupToLocalGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = groupToAdd.Name,
|
|
domain = groupToAdd.Domain
|
|
},
|
|
destinationGroup.Name)).Result;
|
|
}
|
|
|
|
public bool RemovePersonUserFromGroup(PersonUser user, DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin RemoveFromLocalGroupAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.RemoveFromLocalGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = user.Name,
|
|
domain = user.Domain
|
|
},
|
|
group.Name)).Result;
|
|
}
|
|
|
|
public bool RemoveGroupFromGroup(DataTypes.Group groupToRemove, DataTypes.Group group)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin RemoveFromLocalGroupAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.RemoveFromLocalGroupAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = groupToRemove.Name,
|
|
domain = groupToRemove.Domain
|
|
},
|
|
group.Name)).Result;
|
|
}
|
|
|
|
public void ResetPersonUserPassword(PersonUser user, string newPassword)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin ResetLocalPersonUserPasswordAsync operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.ResetLocalPersonUserPasswordAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
user.Name,
|
|
newPassword)).Wait();
|
|
}
|
|
|
|
public void ResetSelfPersonUserPassword(SecureString newPassword)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin ResetLocalPersonUserPasswordAsync operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.ResetSelfLocalPersonUserPasswordAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
SecureStringToString(newPassword))).Wait();
|
|
}
|
|
|
|
public bool UnlockPersonUser(PersonUser user)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin UnlockUserAccountAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.UnlockUserAccountAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = user.Name,
|
|
domain = user.Domain
|
|
})).Result;
|
|
}
|
|
|
|
public bool EnablePersonUser(PersonUser user)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin EnableUserAccountAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.EnableUserAccountAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = user.Name,
|
|
domain = user.Domain
|
|
})).Result;
|
|
}
|
|
|
|
public bool DisablePersonUser(PersonUser user)
|
|
{
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin DisableUserAccountAsync operation
|
|
return authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.DisableUserAccountAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPrincipalManagementService",
|
|
Value = "principalManagementService"
|
|
},
|
|
new SsoPrincipalId
|
|
{
|
|
name = user.Name,
|
|
domain = user.Domain
|
|
})).Result;
|
|
}
|
|
|
|
public PasswordPolicy GetPasswordPolicy()
|
|
{
|
|
PasswordPolicy result = null;
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin GetLocalPasswordPolicyAsync operation
|
|
var ssoAdminPasswordPolicy = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetLocalPasswordPolicyAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPasswordPolicyService",
|
|
Value = "passwordPolicyService"
|
|
})).Result;
|
|
|
|
if (ssoAdminPasswordPolicy != null)
|
|
{
|
|
result = new PasswordPolicy(this)
|
|
{
|
|
Description = ssoAdminPasswordPolicy.description,
|
|
ProhibitedPreviousPasswordsCount = ssoAdminPasswordPolicy.prohibitedPreviousPasswordsCount,
|
|
MinLength = ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.minLength,
|
|
MaxLength = ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.maxLength,
|
|
MaxIdenticalAdjacentCharacters = ssoAdminPasswordPolicy.passwordFormat.maxIdenticalAdjacentCharacters,
|
|
MinNumericCount = ssoAdminPasswordPolicy.passwordFormat.minNumericCount,
|
|
MinSpecialCharCount = ssoAdminPasswordPolicy.passwordFormat.minSpecialCharCount,
|
|
MinAlphabeticCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minAlphabeticCount,
|
|
MinUppercaseCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minUppercaseCount,
|
|
MinLowercaseCount = ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minLowercaseCount,
|
|
PasswordLifetimeDays = ssoAdminPasswordPolicy.passwordLifetimeDays
|
|
};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public PasswordPolicy SetPasswordPolicy(
|
|
string description = null,
|
|
int? prohibitedPreviousPasswordsCount = null,
|
|
int? minLength = null,
|
|
int? maxLength = null,
|
|
int? maxIdenticalAdjacentCharacters = null,
|
|
int? minNumericCount = null,
|
|
int? minSpecialCharCount = null,
|
|
int? minAlphabeticCount = null,
|
|
int? minUppercaseCount = null,
|
|
int? minLowercaseCount = null,
|
|
int? passwordLifetimeDays = null)
|
|
{
|
|
|
|
if (description != null ||
|
|
prohibitedPreviousPasswordsCount != null ||
|
|
minLength != null ||
|
|
maxLength != null ||
|
|
maxIdenticalAdjacentCharacters != null ||
|
|
minNumericCount != null ||
|
|
minSpecialCharCount != null ||
|
|
minAlphabeticCount != null ||
|
|
minUppercaseCount != null ||
|
|
minLowercaseCount != null ||
|
|
passwordLifetimeDays != null)
|
|
{
|
|
|
|
var ssoAdminPasswordPolicy = new SsoAdminPasswordPolicy();
|
|
ssoAdminPasswordPolicy.description = description;
|
|
|
|
if (passwordLifetimeDays != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordLifetimeDays = passwordLifetimeDays.Value;
|
|
ssoAdminPasswordPolicy.passwordLifetimeDaysSpecified = true;
|
|
}
|
|
|
|
if (prohibitedPreviousPasswordsCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.prohibitedPreviousPasswordsCount = prohibitedPreviousPasswordsCount.Value;
|
|
}
|
|
|
|
// Update SsoAdminPasswordFormat if needed
|
|
if (minLength != null ||
|
|
maxLength != null ||
|
|
maxIdenticalAdjacentCharacters != null ||
|
|
minNumericCount != null ||
|
|
minSpecialCharCount != null ||
|
|
minAlphabeticCount != null ||
|
|
minUppercaseCount != null ||
|
|
minLowercaseCount != null)
|
|
{
|
|
|
|
ssoAdminPasswordPolicy.passwordFormat = new SsoAdminPasswordFormat();
|
|
|
|
if (maxIdenticalAdjacentCharacters != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.maxIdenticalAdjacentCharacters = maxIdenticalAdjacentCharacters.Value;
|
|
}
|
|
|
|
if (minNumericCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.minNumericCount = minNumericCount.Value;
|
|
}
|
|
|
|
if (minSpecialCharCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.minSpecialCharCount = minSpecialCharCount.Value;
|
|
}
|
|
|
|
// Update LengthRestriction if needed
|
|
if (minLength != null ||
|
|
maxLength != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction = new SsoAdminPasswordFormatLengthRestriction();
|
|
if (maxLength != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.maxLength = maxLength.Value;
|
|
}
|
|
if (minLength != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.lengthRestriction.minLength = minLength.Value;
|
|
}
|
|
}
|
|
|
|
// Update AlphabeticRestriction if needed
|
|
if (minAlphabeticCount != null ||
|
|
minUppercaseCount != null ||
|
|
minLowercaseCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction = new SsoAdminPasswordFormatAlphabeticRestriction();
|
|
|
|
if (minAlphabeticCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minAlphabeticCount = minAlphabeticCount.Value;
|
|
}
|
|
|
|
if (minUppercaseCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minUppercaseCount = minUppercaseCount.Value;
|
|
}
|
|
|
|
if (minLowercaseCount != null)
|
|
{
|
|
ssoAdminPasswordPolicy.passwordFormat.alphabeticRestriction.minLowercaseCount = minLowercaseCount.Value;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin UpdateLocalPasswordPolicyAsync operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.UpdateLocalPasswordPolicyAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminPasswordPolicyService",
|
|
Value = "passwordPolicyService"
|
|
},
|
|
ssoAdminPasswordPolicy)).Wait();
|
|
}
|
|
|
|
return GetPasswordPolicy();
|
|
}
|
|
|
|
public LockoutPolicy GetLockoutPolicy()
|
|
{
|
|
LockoutPolicy result = null;
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin GetLockoutPolicyAsync operation
|
|
var ssoAdminLockoutPolicy = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetLockoutPolicyAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminLockoutPolicyService",
|
|
Value = "lockoutPolicyService"
|
|
})).Result;
|
|
|
|
if (ssoAdminLockoutPolicy != null)
|
|
{
|
|
result = new LockoutPolicy(this)
|
|
{
|
|
Description = ssoAdminLockoutPolicy.description,
|
|
AutoUnlockIntervalSec = ssoAdminLockoutPolicy.autoUnlockIntervalSec,
|
|
FailedAttemptIntervalSec = ssoAdminLockoutPolicy.failedAttemptIntervalSec,
|
|
MaxFailedAttempts = ssoAdminLockoutPolicy.maxFailedAttempts
|
|
};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public LockoutPolicy SetLockoutPolicy(
|
|
string description,
|
|
long? autoUnlockIntervalSec,
|
|
long? failedAttemptIntervalSec,
|
|
int? maxFailedAttempts)
|
|
{
|
|
|
|
if (description != null ||
|
|
autoUnlockIntervalSec != null ||
|
|
failedAttemptIntervalSec != null ||
|
|
maxFailedAttempts != null)
|
|
{
|
|
|
|
var ssoAdminLockoutPolicy = new SsoAdminLockoutPolicy();
|
|
|
|
ssoAdminLockoutPolicy.description = description;
|
|
|
|
if (autoUnlockIntervalSec != null)
|
|
{
|
|
ssoAdminLockoutPolicy.autoUnlockIntervalSec = autoUnlockIntervalSec.Value;
|
|
}
|
|
|
|
if (failedAttemptIntervalSec != null)
|
|
{
|
|
ssoAdminLockoutPolicy.failedAttemptIntervalSec = failedAttemptIntervalSec.Value;
|
|
}
|
|
|
|
if (maxFailedAttempts != null)
|
|
{
|
|
ssoAdminLockoutPolicy.maxFailedAttempts = maxFailedAttempts.Value;
|
|
}
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
// Invoke SSO Admin GetLockoutPolicyAsync operation
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.UpdateLockoutPolicyAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminLockoutPolicyService",
|
|
Value = "lockoutPolicyService"
|
|
},
|
|
ssoAdminLockoutPolicy)).Wait();
|
|
|
|
}
|
|
|
|
return GetLockoutPolicy();
|
|
}
|
|
|
|
public TokenLifetime GetTokenLifetime()
|
|
{
|
|
|
|
// Create Authorization Invocation Context
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
var maxHoKTokenLifetime = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetMaximumHoKTokenLifetimeAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminConfigurationManagementService",
|
|
Value = "configurationManagementService"
|
|
})).Result;
|
|
|
|
var maxBearerTokenLifetime = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetMaximumBearerTokenLifetimeAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminConfigurationManagementService",
|
|
Value = "configurationManagementService"
|
|
})).Result;
|
|
|
|
return new TokenLifetime(this)
|
|
{
|
|
MaxHoKTokenLifetime = maxHoKTokenLifetime,
|
|
MaxBearerTokenLifetime = maxBearerTokenLifetime
|
|
};
|
|
}
|
|
|
|
public TokenLifetime SetTokenLifetime(
|
|
long? maxHoKTokenLifetime,
|
|
long? maxBearerTokenLifetime)
|
|
{
|
|
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
if (maxHoKTokenLifetime != null)
|
|
{
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.SetMaximumHoKTokenLifetimeAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminConfigurationManagementService",
|
|
Value = "configurationManagementService"
|
|
},
|
|
maxHoKTokenLifetime.Value)).Wait();
|
|
}
|
|
|
|
if (maxBearerTokenLifetime != null)
|
|
{
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.SetMaximumBearerTokenLifetimeAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminConfigurationManagementService",
|
|
Value = "configurationManagementService"
|
|
},
|
|
maxBearerTokenLifetime.Value)).Wait();
|
|
}
|
|
|
|
|
|
return GetTokenLifetime();
|
|
}
|
|
|
|
public void AddActiveDirectoryExternalDomain(
|
|
string domainName,
|
|
string domainAlias,
|
|
string friendlyName,
|
|
string primaryUrl,
|
|
string baseDNUsers,
|
|
string baseDNGroups,
|
|
string authenticationUserName,
|
|
string authenticationPassword,
|
|
string serverType)
|
|
{
|
|
|
|
string authenticationType = "password";
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.AddExternalDomainAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminDomainManagementService",
|
|
Value = "domainManagementService"
|
|
},
|
|
serverType,
|
|
domainName,
|
|
domainAlias,
|
|
new SsoAdminExternalDomainDetails
|
|
{
|
|
friendlyName = friendlyName,
|
|
primaryUrl = primaryUrl,
|
|
userBaseDn = baseDNUsers,
|
|
groupBaseDn = baseDNGroups
|
|
},
|
|
authenticationType,
|
|
new SsoAdminDomainManagementServiceAuthenticationCredentails
|
|
{
|
|
username = authenticationUserName,
|
|
password = authenticationPassword
|
|
})).Wait();
|
|
}
|
|
|
|
public void AddLdapIdentitySource(
|
|
string domainName,
|
|
string domainAlias,
|
|
string friendlyName,
|
|
string primaryUrl,
|
|
string failoverUrl,
|
|
string baseDNUsers,
|
|
string baseDNGroups,
|
|
string authenticationUserName,
|
|
string authenticationPassword,
|
|
string serverType,
|
|
X509Certificate2[] ldapCertificates)
|
|
{
|
|
|
|
string authenticationType = "password";
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
var adminLdapIdentitySourceDetails = new SsoAdminLdapIdentitySourceDetails
|
|
{
|
|
friendlyName = friendlyName,
|
|
primaryUrl = primaryUrl,
|
|
failoverUrl = failoverUrl,
|
|
userBaseDn = baseDNUsers,
|
|
groupBaseDn = baseDNGroups
|
|
};
|
|
|
|
if (ldapCertificates != null && ldapCertificates.Length > 0)
|
|
{
|
|
var certificates = new List<string>();
|
|
foreach (var ldapCert in ldapCertificates)
|
|
{
|
|
certificates.Add(Convert.ToBase64String(ldapCert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
|
|
}
|
|
|
|
if (certificates.Count > 0)
|
|
{
|
|
adminLdapIdentitySourceDetails.certificates = certificates.ToArray();
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.RegisterLdapAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminIdentitySourceManagementService",
|
|
Value = "identitySourceManagementService"
|
|
},
|
|
serverType,
|
|
domainName,
|
|
domainAlias,
|
|
adminLdapIdentitySourceDetails,
|
|
authenticationType,
|
|
new SsoAdminIdentitySourceManagementServiceAuthenticationCredentials
|
|
{
|
|
username = authenticationUserName,
|
|
password = authenticationPassword
|
|
})).Wait();
|
|
}
|
|
catch (AggregateException e)
|
|
{
|
|
throw e.InnerException;
|
|
}
|
|
}
|
|
|
|
public void UpdateLdapIdentitySource(
|
|
string name,
|
|
string friendlyName,
|
|
string primaryUrl,
|
|
string failoverUrl,
|
|
string baseDNUsers,
|
|
string baseDNGroups,
|
|
X509Certificate2[] ldapCertificates)
|
|
{
|
|
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
var adminLdapIdentitySourceDetails = new SsoAdminLdapIdentitySourceDetails
|
|
{
|
|
friendlyName = friendlyName,
|
|
primaryUrl = primaryUrl,
|
|
failoverUrl = failoverUrl,
|
|
userBaseDn = baseDNUsers,
|
|
groupBaseDn = baseDNGroups
|
|
};
|
|
|
|
if (ldapCertificates != null && ldapCertificates.Length > 0)
|
|
{
|
|
var certificates = new List<string>();
|
|
foreach (var ldapCert in ldapCertificates)
|
|
{
|
|
certificates.Add(Convert.ToBase64String(ldapCert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks));
|
|
}
|
|
|
|
if (certificates.Count > 0)
|
|
{
|
|
adminLdapIdentitySourceDetails.certificates = certificates.ToArray();
|
|
}
|
|
}
|
|
|
|
try
|
|
{
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.UpdateLdapAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminIdentitySourceManagementService",
|
|
Value = "identitySourceManagementService"
|
|
},
|
|
name,
|
|
adminLdapIdentitySourceDetails)).Wait();
|
|
}
|
|
catch (AggregateException e)
|
|
{
|
|
throw e.InnerException;
|
|
}
|
|
}
|
|
|
|
public IEnumerable<IdentitySource> GetDomains()
|
|
{
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
var domains = authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.GetDomainsAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminDomainManagementService",
|
|
Value = "domainManagementService"
|
|
})).Result;
|
|
|
|
if (domains != null)
|
|
{
|
|
var localos = new LocalOSIdentitySource();
|
|
localos.Name = domains.localOSDomainName;
|
|
yield return localos;
|
|
|
|
var system = new SystemIdentitySource();
|
|
system.Name = domains.systemDomainName;
|
|
yield return system;
|
|
|
|
if (domains.externalDomains != null && domains.externalDomains.Length > 0)
|
|
{
|
|
foreach (var externalDomain in domains.externalDomains)
|
|
{
|
|
var extIdentitySource = new ActiveDirectoryIdentitySource();
|
|
extIdentitySource.Name = externalDomain.name;
|
|
extIdentitySource.Alias = externalDomain.alias;
|
|
extIdentitySource.Type = externalDomain.type;
|
|
extIdentitySource.AuthenticationType = externalDomain.authenticationDetails?.authenticationType;
|
|
extIdentitySource.AuthenticationUsername = externalDomain.authenticationDetails?.username;
|
|
extIdentitySource.FriendlyName = externalDomain.details?.friendlyName;
|
|
extIdentitySource.PrimaryUrl = externalDomain.details?.primaryUrl;
|
|
extIdentitySource.FailoverUrl = externalDomain.details?.failoverUrl;
|
|
extIdentitySource.GroupBaseDN = externalDomain.details?.groupBaseDn;
|
|
extIdentitySource.UserBaseDN = externalDomain.details?.userBaseDn;
|
|
yield return extIdentitySource;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DeleteDomain(string name)
|
|
{
|
|
|
|
var authorizedInvocationContext =
|
|
CreateAuthorizedInvocationContext();
|
|
|
|
try
|
|
{
|
|
authorizedInvocationContext.
|
|
InvokeOperation(() =>
|
|
_ssoAdminBindingClient.DeleteAsync(
|
|
new ManagedObjectReference
|
|
{
|
|
type = "SsoAdminIdentitySourceManagementService",
|
|
Value = "identitySourceManagementService"
|
|
},
|
|
name)).Wait();
|
|
}
|
|
catch (AggregateException e)
|
|
{
|
|
throw e.InnerException;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|