github.com/nats-io/jwt/v2@v2.5.6/authorization_claims.go (about)

     1  /*
     2   * Copyright 2022 The NATS Authors
     3   * Licensed under the Apache License, Version 2.0 (the "License");
     4   * you may not use this file except in compliance with the License.
     5   * You may obtain a copy of the License at
     6   *
     7   * http://www.apache.org/licenses/LICENSE-2.0
     8   *
     9   * Unless required by applicable law or agreed to in writing, software
    10   * distributed under the License is distributed on an "AS IS" BASIS,
    11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   * See the License for the specific language governing permissions and
    13   * limitations under the License.
    14   */
    15  
    16  package jwt
    17  
    18  import (
    19  	"errors"
    20  
    21  	"github.com/nats-io/nkeys"
    22  )
    23  
    24  // ServerID is basic static info for a NATS server.
    25  type ServerID struct {
    26  	Name    string  `json:"name"`
    27  	Host    string  `json:"host"`
    28  	ID      string  `json:"id"`
    29  	Version string  `json:"version,omitempty"`
    30  	Cluster string  `json:"cluster,omitempty"`
    31  	Tags    TagList `json:"tags,omitempty"`
    32  	XKey    string  `json:"xkey,omitempty"`
    33  }
    34  
    35  // ClientInformation is information about a client that is trying to authorize.
    36  type ClientInformation struct {
    37  	Host    string  `json:"host,omitempty"`
    38  	ID      uint64  `json:"id,omitempty"`
    39  	User    string  `json:"user,omitempty"`
    40  	Name    string  `json:"name,omitempty"`
    41  	Tags    TagList `json:"tags,omitempty"`
    42  	NameTag string  `json:"name_tag,omitempty"`
    43  	Kind    string  `json:"kind,omitempty"`
    44  	Type    string  `json:"type,omitempty"`
    45  	MQTT    string  `json:"mqtt_id,omitempty"`
    46  	Nonce   string  `json:"nonce,omitempty"`
    47  }
    48  
    49  // ConnectOptions represents options that were set in the CONNECT protocol from the client
    50  // during authorization.
    51  type ConnectOptions struct {
    52  	JWT         string `json:"jwt,omitempty"`
    53  	Nkey        string `json:"nkey,omitempty"`
    54  	SignedNonce string `json:"sig,omitempty"`
    55  	Token       string `json:"auth_token,omitempty"`
    56  	Username    string `json:"user,omitempty"`
    57  	Password    string `json:"pass,omitempty"`
    58  	Name        string `json:"name,omitempty"`
    59  	Lang        string `json:"lang,omitempty"`
    60  	Version     string `json:"version,omitempty"`
    61  	Protocol    int    `json:"protocol"`
    62  }
    63  
    64  // ClientTLS is information about TLS state if present, including client certs.
    65  // If the client certs were present and verified they will be under verified chains
    66  // with the client peer cert being VerifiedChains[0]. These are complete and pem encoded.
    67  // If they were not verified, they will be under certs.
    68  type ClientTLS struct {
    69  	Version        string       `json:"version,omitempty"`
    70  	Cipher         string       `json:"cipher,omitempty"`
    71  	Certs          StringList   `json:"certs,omitempty"`
    72  	VerifiedChains []StringList `json:"verified_chains,omitempty"`
    73  }
    74  
    75  // AuthorizationRequest represents all the information we know about the client that
    76  // will be sent to an external authorization service.
    77  type AuthorizationRequest struct {
    78  	Server            ServerID          `json:"server_id"`
    79  	UserNkey          string            `json:"user_nkey"`
    80  	ClientInformation ClientInformation `json:"client_info"`
    81  	ConnectOptions    ConnectOptions    `json:"connect_opts"`
    82  	TLS               *ClientTLS        `json:"client_tls,omitempty"`
    83  	RequestNonce      string            `json:"request_nonce,omitempty"`
    84  	GenericFields
    85  }
    86  
    87  // AuthorizationRequestClaims defines an external auth request JWT.
    88  // These wil be signed by a NATS server.
    89  type AuthorizationRequestClaims struct {
    90  	ClaimsData
    91  	AuthorizationRequest `json:"nats"`
    92  }
    93  
    94  // NewAuthorizationRequestClaims creates an auth request JWT with the specific subject/public key.
    95  func NewAuthorizationRequestClaims(subject string) *AuthorizationRequestClaims {
    96  	if subject == "" {
    97  		return nil
    98  	}
    99  	var ac AuthorizationRequestClaims
   100  	ac.Subject = subject
   101  	return &ac
   102  }
   103  
   104  // Validate checks the generic and specific parts of the auth request jwt.
   105  func (ac *AuthorizationRequestClaims) Validate(vr *ValidationResults) {
   106  	if ac.UserNkey == "" {
   107  		vr.AddError("User nkey is required")
   108  	} else if !nkeys.IsValidPublicUserKey(ac.UserNkey) {
   109  		vr.AddError("User nkey %q is not a valid user public key", ac.UserNkey)
   110  	}
   111  	ac.ClaimsData.Validate(vr)
   112  }
   113  
   114  // Encode tries to turn the auth request claims into a JWT string.
   115  func (ac *AuthorizationRequestClaims) Encode(pair nkeys.KeyPair) (string, error) {
   116  	ac.Type = AuthorizationRequestClaim
   117  	return ac.ClaimsData.encode(pair, ac)
   118  }
   119  
   120  // DecodeAuthorizationRequestClaims tries to parse an auth request claims from a JWT string
   121  func DecodeAuthorizationRequestClaims(token string) (*AuthorizationRequestClaims, error) {
   122  	claims, err := Decode(token)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	ac, ok := claims.(*AuthorizationRequestClaims)
   127  	if !ok {
   128  		return nil, errors.New("not an authorization request claim")
   129  	}
   130  	return ac, nil
   131  }
   132  
   133  // ExpectedPrefixes defines the types that can encode an auth request jwt, servers.
   134  func (ac *AuthorizationRequestClaims) ExpectedPrefixes() []nkeys.PrefixByte {
   135  	return []nkeys.PrefixByte{nkeys.PrefixByteServer}
   136  }
   137  
   138  func (ac *AuthorizationRequestClaims) ClaimType() ClaimType {
   139  	return ac.Type
   140  }
   141  
   142  // Claims returns the request claims data.
   143  func (ac *AuthorizationRequestClaims) Claims() *ClaimsData {
   144  	return &ac.ClaimsData
   145  }
   146  
   147  // Payload pulls the request specific payload out of the claims.
   148  func (ac *AuthorizationRequestClaims) Payload() interface{} {
   149  	return &ac.AuthorizationRequest
   150  }
   151  
   152  func (ac *AuthorizationRequestClaims) String() string {
   153  	return ac.ClaimsData.String(ac)
   154  }
   155  
   156  func (ac *AuthorizationRequestClaims) updateVersion() {
   157  	ac.GenericFields.Version = libVersion
   158  }
   159  
   160  type AuthorizationResponse struct {
   161  	Jwt   string `json:"jwt,omitempty"`
   162  	Error string `json:"error,omitempty"`
   163  	// IssuerAccount stores the public key for the account the issuer represents.
   164  	// When set, the claim was issued by a signing key.
   165  	IssuerAccount string `json:"issuer_account,omitempty"`
   166  	GenericFields
   167  }
   168  
   169  type AuthorizationResponseClaims struct {
   170  	ClaimsData
   171  	AuthorizationResponse `json:"nats"`
   172  }
   173  
   174  func NewAuthorizationResponseClaims(subject string) *AuthorizationResponseClaims {
   175  	if subject == "" {
   176  		return nil
   177  	}
   178  	var ac AuthorizationResponseClaims
   179  	ac.Subject = subject
   180  	return &ac
   181  }
   182  
   183  // DecodeAuthorizationResponseClaims tries to parse an auth request claims from a JWT string
   184  func DecodeAuthorizationResponseClaims(token string) (*AuthorizationResponseClaims, error) {
   185  	claims, err := Decode(token)
   186  	if err != nil {
   187  		return nil, err
   188  	}
   189  	ac, ok := claims.(*AuthorizationResponseClaims)
   190  	if !ok {
   191  		return nil, errors.New("not an authorization request claim")
   192  	}
   193  	return ac, nil
   194  }
   195  
   196  // ExpectedPrefixes defines the types that can encode an auth request jwt, servers.
   197  func (ar *AuthorizationResponseClaims) ExpectedPrefixes() []nkeys.PrefixByte {
   198  	return []nkeys.PrefixByte{nkeys.PrefixByteAccount}
   199  }
   200  
   201  func (ar *AuthorizationResponseClaims) ClaimType() ClaimType {
   202  	return ar.Type
   203  }
   204  
   205  // Claims returns the request claims data.
   206  func (ar *AuthorizationResponseClaims) Claims() *ClaimsData {
   207  	return &ar.ClaimsData
   208  }
   209  
   210  // Payload pulls the request specific payload out of the claims.
   211  func (ar *AuthorizationResponseClaims) Payload() interface{} {
   212  	return &ar.AuthorizationResponse
   213  }
   214  
   215  func (ar *AuthorizationResponseClaims) String() string {
   216  	return ar.ClaimsData.String(ar)
   217  }
   218  
   219  func (ar *AuthorizationResponseClaims) updateVersion() {
   220  	ar.GenericFields.Version = libVersion
   221  }
   222  
   223  // Validate checks the generic and specific parts of the auth request jwt.
   224  func (ar *AuthorizationResponseClaims) Validate(vr *ValidationResults) {
   225  	if !nkeys.IsValidPublicUserKey(ar.Subject) {
   226  		vr.AddError("Subject must be a user public key")
   227  	}
   228  	if !nkeys.IsValidPublicServerKey(ar.Audience) {
   229  		vr.AddError("Audience must be a server public key")
   230  	}
   231  	if ar.Error == "" && ar.Jwt == "" {
   232  		vr.AddError("Error or Jwt is required")
   233  	}
   234  	if ar.Error != "" && ar.Jwt != "" {
   235  		vr.AddError("Only Error or Jwt can be set")
   236  	}
   237  	if ar.IssuerAccount != "" && !nkeys.IsValidPublicAccountKey(ar.IssuerAccount) {
   238  		vr.AddError("issuer_account is not an account public key")
   239  	}
   240  	ar.ClaimsData.Validate(vr)
   241  }
   242  
   243  // Encode tries to turn the auth request claims into a JWT string.
   244  func (ar *AuthorizationResponseClaims) Encode(pair nkeys.KeyPair) (string, error) {
   245  	ar.Type = AuthorizationResponseClaim
   246  	return ar.ClaimsData.encode(pair, ar)
   247  }