credentials.go 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. *
  3. * Copyright 2014 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. // Package credentials implements various credentials supported by gRPC library,
  19. // which encapsulate all the state needed by a client to authenticate with a
  20. // server and make various assertions, e.g., about the client's identity, role,
  21. // or whether it is authorized to make a particular call.
  22. package credentials // import "google.golang.org/grpc/credentials"
  23. import (
  24. "context"
  25. "errors"
  26. "fmt"
  27. "net"
  28. "github.com/golang/protobuf/proto"
  29. "google.golang.org/grpc/internal"
  30. )
  31. // PerRPCCredentials defines the common interface for the credentials which need to
  32. // attach security information to every RPC (e.g., oauth2).
  33. type PerRPCCredentials interface {
  34. // GetRequestMetadata gets the current request metadata, refreshing
  35. // tokens if required. This should be called by the transport layer on
  36. // each request, and the data should be populated in headers or other
  37. // context. If a status code is returned, it will be used as the status
  38. // for the RPC. uri is the URI of the entry point for the request.
  39. // When supported by the underlying implementation, ctx can be used for
  40. // timeout and cancellation. Additionally, RequestInfo data will be
  41. // available via ctx to this call.
  42. // TODO(zhaoq): Define the set of the qualified keys instead of leaving
  43. // it as an arbitrary string.
  44. GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error)
  45. // RequireTransportSecurity indicates whether the credentials requires
  46. // transport security.
  47. RequireTransportSecurity() bool
  48. }
  49. // SecurityLevel defines the protection level on an established connection.
  50. //
  51. // This API is experimental.
  52. type SecurityLevel int
  53. const (
  54. // NoSecurity indicates a connection is insecure.
  55. // The zero SecurityLevel value is invalid for backward compatibility.
  56. NoSecurity SecurityLevel = iota + 1
  57. // IntegrityOnly indicates a connection only provides integrity protection.
  58. IntegrityOnly
  59. // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection.
  60. PrivacyAndIntegrity
  61. )
  62. // String returns SecurityLevel in a string format.
  63. func (s SecurityLevel) String() string {
  64. switch s {
  65. case NoSecurity:
  66. return "NoSecurity"
  67. case IntegrityOnly:
  68. return "IntegrityOnly"
  69. case PrivacyAndIntegrity:
  70. return "PrivacyAndIntegrity"
  71. }
  72. return fmt.Sprintf("invalid SecurityLevel: %v", int(s))
  73. }
  74. // CommonAuthInfo contains authenticated information common to AuthInfo implementations.
  75. // It should be embedded in a struct implementing AuthInfo to provide additional information
  76. // about the credentials.
  77. //
  78. // This API is experimental.
  79. type CommonAuthInfo struct {
  80. SecurityLevel SecurityLevel
  81. }
  82. // GetCommonAuthInfo returns the pointer to CommonAuthInfo struct.
  83. func (c *CommonAuthInfo) GetCommonAuthInfo() *CommonAuthInfo {
  84. return c
  85. }
  86. // ProtocolInfo provides information regarding the gRPC wire protocol version,
  87. // security protocol, security protocol version in use, server name, etc.
  88. type ProtocolInfo struct {
  89. // ProtocolVersion is the gRPC wire protocol version.
  90. ProtocolVersion string
  91. // SecurityProtocol is the security protocol in use.
  92. SecurityProtocol string
  93. // SecurityVersion is the security protocol version.
  94. SecurityVersion string
  95. // ServerName is the user-configured server name.
  96. ServerName string
  97. }
  98. // AuthInfo defines the common interface for the auth information the users are interested in.
  99. // A struct that implements AuthInfo should embed CommonAuthInfo by including additional
  100. // information about the credentials in it.
  101. type AuthInfo interface {
  102. AuthType() string
  103. }
  104. // ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
  105. // and the caller should not close rawConn.
  106. var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
  107. // TransportCredentials defines the common interface for all the live gRPC wire
  108. // protocols and supported transport security protocols (e.g., TLS, SSL).
  109. type TransportCredentials interface {
  110. // ClientHandshake does the authentication handshake specified by the corresponding
  111. // authentication protocol on rawConn for clients. It returns the authenticated
  112. // connection and the corresponding auth information about the connection.
  113. // The auth information should embed CommonAuthInfo to return additional information about
  114. // the credentials. Implementations must use the provided context to implement timely cancellation.
  115. // gRPC will try to reconnect if the error returned is a temporary error
  116. // (io.EOF, context.DeadlineExceeded or err.Temporary() == true).
  117. // If the returned error is a wrapper error, implementations should make sure that
  118. // the error implements Temporary() to have the correct retry behaviors.
  119. //
  120. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  121. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error)
  122. // ServerHandshake does the authentication handshake for servers. It returns
  123. // the authenticated connection and the corresponding auth information about
  124. // the connection. The auth information should embed CommonAuthInfo to return additional information
  125. // about the credentials.
  126. //
  127. // If the returned net.Conn is closed, it MUST close the net.Conn provided.
  128. ServerHandshake(net.Conn) (net.Conn, AuthInfo, error)
  129. // Info provides the ProtocolInfo of this TransportCredentials.
  130. Info() ProtocolInfo
  131. // Clone makes a copy of this TransportCredentials.
  132. Clone() TransportCredentials
  133. // OverrideServerName overrides the server name used to verify the hostname on the returned certificates from the server.
  134. // gRPC internals also use it to override the virtual hosting name if it is set.
  135. // It must be called before dialing. Currently, this is only used by grpclb.
  136. OverrideServerName(string) error
  137. }
  138. // Bundle is a combination of TransportCredentials and PerRPCCredentials.
  139. //
  140. // It also contains a mode switching method, so it can be used as a combination
  141. // of different credential policies.
  142. //
  143. // Bundle cannot be used together with individual TransportCredentials.
  144. // PerRPCCredentials from Bundle will be appended to other PerRPCCredentials.
  145. //
  146. // This API is experimental.
  147. type Bundle interface {
  148. TransportCredentials() TransportCredentials
  149. PerRPCCredentials() PerRPCCredentials
  150. // NewWithMode should make a copy of Bundle, and switch mode. Modifying the
  151. // existing Bundle may cause races.
  152. //
  153. // NewWithMode returns nil if the requested mode is not supported.
  154. NewWithMode(mode string) (Bundle, error)
  155. }
  156. // RequestInfo contains request data attached to the context passed to GetRequestMetadata calls.
  157. //
  158. // This API is experimental.
  159. type RequestInfo struct {
  160. // The method passed to Invoke or NewStream for this RPC. (For proto methods, this has the format "/some.Service/Method")
  161. Method string
  162. // AuthInfo contains the information from a security handshake (TransportCredentials.ClientHandshake, TransportCredentials.ServerHandshake)
  163. AuthInfo AuthInfo
  164. }
  165. // requestInfoKey is a struct to be used as the key when attaching a RequestInfo to a context object.
  166. type requestInfoKey struct{}
  167. // RequestInfoFromContext extracts the RequestInfo from the context if it exists.
  168. //
  169. // This API is experimental.
  170. func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) {
  171. ri, ok = ctx.Value(requestInfoKey{}).(RequestInfo)
  172. return
  173. }
  174. // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
  175. // It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
  176. // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
  177. //
  178. // This API is experimental.
  179. func CheckSecurityLevel(ctx context.Context, level SecurityLevel) error {
  180. type internalInfo interface {
  181. GetCommonAuthInfo() *CommonAuthInfo
  182. }
  183. ri, _ := RequestInfoFromContext(ctx)
  184. if ri.AuthInfo == nil {
  185. return errors.New("unable to obtain SecurityLevel from context")
  186. }
  187. if ci, ok := ri.AuthInfo.(internalInfo); ok {
  188. // CommonAuthInfo.SecurityLevel has an invalid value.
  189. if ci.GetCommonAuthInfo().SecurityLevel == 0 {
  190. return nil
  191. }
  192. if ci.GetCommonAuthInfo().SecurityLevel < level {
  193. return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
  194. }
  195. }
  196. // The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
  197. return nil
  198. }
  199. func init() {
  200. internal.NewRequestInfoContext = func(ctx context.Context, ri RequestInfo) context.Context {
  201. return context.WithValue(ctx, requestInfoKey{}, ri)
  202. }
  203. }
  204. // ChannelzSecurityInfo defines the interface that security protocols should implement
  205. // in order to provide security info to channelz.
  206. //
  207. // This API is experimental.
  208. type ChannelzSecurityInfo interface {
  209. GetSecurityValue() ChannelzSecurityValue
  210. }
  211. // ChannelzSecurityValue defines the interface that GetSecurityValue() return value
  212. // should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
  213. // and *OtherChannelzSecurityValue.
  214. //
  215. // This API is experimental.
  216. type ChannelzSecurityValue interface {
  217. isChannelzSecurityValue()
  218. }
  219. // OtherChannelzSecurityValue defines the struct that non-TLS protocol should return
  220. // from GetSecurityValue(), which contains protocol specific security info. Note
  221. // the Value field will be sent to users of channelz requesting channel info, and
  222. // thus sensitive info should better be avoided.
  223. //
  224. // This API is experimental.
  225. type OtherChannelzSecurityValue struct {
  226. ChannelzSecurityValue
  227. Name string
  228. Value proto.Message
  229. }