/// <summary> /// Add a credentials object /// </summary> /// <param name="principal">The security principal</param> /// <param name="credentials">The credentials object (depends on type)</param> public void AddCredentials(SecurityPrincipal principal, ICredentialObject credentials) { lock (_cachedCredentials) { _cachedCredentials[principal] = credentials; } }
/// <summary> /// Request credentials for a particular purpose /// </summary> /// <param name="type">The type of credentials, for example X509CertificateContainer</param> /// <param name="name">Principal name, e.g. a username, can be empty</param> /// <param name="realm">The principal realm, used to determine the target of the credentials, e.g. a domain</param> /// <param name="details">A textual description in case the user has to pick</param> /// <param name="validateCredentials">A callback method to validate the credentials before placing them in the store, only called /// when new credentials are requested, not cached (as they are assumed to be valid). Can be null</param> /// <param name="context">An arbitrary context, passed in to the function for use by the authenticator and the gathering of credentials</param> /// <returns>The credentials object (depends on type)</returns> /// <exception cref="ArgumentException">Thrown if type not derived from ICredentialObject</exception> public ICredentialObject RequestCredentials(Type type, string name, string realm, string details, Func <ICredentialObject, object, bool> validateCredentials, object context) { if (type == null) { throw new ArgumentNullException("type"); } if (!typeof(ICredentialObject).IsAssignableFrom(type)) { throw new ArgumentException(Properties.Resources.CredentialsManagerService_TypeMustDeriveFromICredentialObject); } SecurityPrincipal principal = new SecurityPrincipal(type, name, realm); ICredentialObject ret = GetCachedCredentials(principal); if (ret == null) { ret = GetCredentials(principal, details, validateCredentials, context); } return(ret); }
private ICredentialObject GetCredentials(SecurityPrincipal principal, string details, Func <ICredentialObject, object, bool> validateCredentials, object context) { ICredentialObject ret = null; if (ResolveCredentials != null) { bool resolved = false; // Exit if we tried to resolve or ret is not null while (!resolved) { // Resolve a single principal only one at a time object lockObject = new object(); object currObject = _resolveLock.GetOrAdd(principal, lockObject); lock (currObject) { // This is our object, and we know it is already locked if (currObject == lockObject) { try { ResolveCredentialsEventArgs args = new ResolveCredentialsEventArgs(principal, details, context); ResolveCredentials(this, args); ResolveCredentialsResult credentials = args.Result; if ((credentials != null) && (credentials.Credentials != null)) { if (validateCredentials == null || validateCredentials(credentials.Credentials, context)) { // Perhaps should log this as an error? if (principal.PrincipalType.IsAssignableFrom(credentials.Credentials.GetType())) { if (credentials.Cache) { AddCredentials(principal, credentials.Credentials); } ret = credentials.Credentials; break; } } } resolved = true; } finally { _resolveLock.TryRemove(principal, out lockObject); } } else // Not our object, but doesn't matter we won't get here until the originator unlocks { ret = GetCachedCredentials(principal); if (ret != null) { resolved = true; } } } } } return(ret); }
/// <summary> /// Constructor /// </summary> /// <param name="credentials">The credentials</param> /// <param name="cache">Whether to cache the credentials</param> public ResolveCredentialsResult(ICredentialObject credentials, bool cache) { Credentials = credentials; Cache = cache; }
/// <summary> /// Constructor /// </summary> /// <param name="credentials">The credentials</param> public ResolveCredentialsResult(ICredentialObject credentials) : this(credentials, true) { }
/// <summary> /// Constructor /// </summary> /// <param name="credentials">The credentials</param> /// <param name="cache">Whether to cache the credentials</param> public ResolveCredentialsResult(ICredentialObject credentials, bool cache) { Credentials = credentials; Cache = cache; }
/// <summary> /// Constructor /// </summary> /// <param name="credentials">The credentials</param> public ResolveCredentialsResult(ICredentialObject credentials) : this(credentials, true) { }