aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/Grpc.Core/CallCredentials.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/Grpc.Core/CallCredentials.cs')
-rw-r--r--src/csharp/Grpc.Core/CallCredentials.cs142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs
new file mode 100644
index 0000000000..809c9f412d
--- /dev/null
+++ b/src/csharp/Grpc.Core/CallCredentials.cs
@@ -0,0 +1,142 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Client-side call credentials. Provide authorization with per-call granularity.
+ /// </summary>
+ public abstract class CallCredentials
+ {
+ /// <summary>
+ /// Composes multiple multiple <c>CallCredentials</c> objects into
+ /// a single <c>CallCredentials</c> object.
+ /// </summary>
+ /// <param name="credentials">credentials to compose</param>
+ /// <returns>The new <c>CompositeCallCredentials</c></returns>
+ public static CallCredentials Compose(params CallCredentials[] credentials)
+ {
+ return new CompositeCallCredentials(credentials);
+ }
+
+ /// <summary>
+ /// Creates native object for the credentials.
+ /// </summary>
+ /// <returns>The native credentials.</returns>
+ internal abstract CredentialsSafeHandle ToNativeCredentials();
+ }
+
+ /// <summary>
+ /// Asynchronous authentication interceptor for <see cref="MetadataCredentials"/>.
+ /// </summary>
+ /// <param name="authUri">URL of a service to which current remote call needs to authenticate</param>
+ /// <param name="metadata">Metadata to populate with entries that will be added to outgoing call's headers.</param>
+ /// <returns></returns>
+ public delegate Task AsyncAuthInterceptor(string authUri, Metadata metadata);
+
+ /// <summary>
+ /// Client-side credentials that delegate metadata based auth to an interceptor.
+ /// The interceptor is automatically invoked for each remote call that uses <c>MetadataCredentials.</c>
+ /// </summary>
+ public class MetadataCredentials : CallCredentials
+ {
+ readonly AsyncAuthInterceptor interceptor;
+
+ /// <summary>
+ /// Initializes a new instance of <c>MetadataCredentials</c> class.
+ /// </summary>
+ /// <param name="interceptor">authentication interceptor</param>
+ public MetadataCredentials(AsyncAuthInterceptor interceptor)
+ {
+ this.interceptor = interceptor;
+ }
+
+ internal override CredentialsSafeHandle ToNativeCredentials()
+ {
+ NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor);
+ return plugin.Credentials;
+ }
+ }
+
+ /// <summary>
+ /// Credentials that allow composing multiple credentials objects into one <see cref="CallCredentials"/> object.
+ /// </summary>
+ internal sealed class CompositeCallCredentials : CallCredentials
+ {
+ readonly List<CallCredentials> credentials;
+
+ /// <summary>
+ /// Initializes a new instance of <c>CompositeCallCredentials</c> class.
+ /// The resulting credentials object will be composite of all the credentials specified as parameters.
+ /// </summary>
+ /// <param name="credentials">credentials to compose</param>
+ public CompositeCallCredentials(params CallCredentials[] credentials)
+ {
+ Preconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials.");
+ this.credentials = new List<CallCredentials>(credentials);
+ }
+
+ internal override CredentialsSafeHandle ToNativeCredentials()
+ {
+ return ToNativeRecursive(0);
+ }
+
+ // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier.
+ // In practice, we won't usually see composites from more than two credentials anyway.
+ private CredentialsSafeHandle ToNativeRecursive(int startIndex)
+ {
+ if (startIndex == credentials.Count - 1)
+ {
+ return credentials[startIndex].ToNativeCredentials();
+ }
+
+ using (var cred1 = credentials[startIndex].ToNativeCredentials())
+ using (var cred2 = ToNativeRecursive(startIndex + 1))
+ {
+ var nativeComposite = CredentialsSafeHandle.CreateComposite(cred1, cred2);
+ if (nativeComposite.IsInvalid)
+ {
+ throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials.");
+ }
+ return nativeComposite;
+ }
+ }
+ }
+}