Documentation
¶
Overview ¶
Package azureauth implements Azure Storage's SharedKey and SharedKeyLite Authorization-header scheme: structural parsing of the header, the canonicalization + HMAC-SHA256 signing algorithm described in Microsoft's "Authorize with Shared Key" REST reference, and an explicit, opt-in verification call.
It is intentionally self-contained (standard library only) so it can be shared by every Azure-flavoured service package (blob, queue, table, cosmosdb) without any of them depending on one another.
Mirroring the rest of gopherstack's auth philosophy (see services/s3/sigv4.go), this package is permissive by default: parsing an Authorization header never fails because a signature happens to be wrong, and nothing in the parsing path performs cryptographic verification. Callers that want enforcement call VerifySharedKey explicitly.
Index ¶
- Constants
- Variables
- func CanonicalizedHeaders(r *http.Request) string
- func CanonicalizedResource(account string, u *url.URL) string
- func SignSharedKey(r *http.Request, account, accountKey string) (string, error)
- func SignSharedKeyLite(r *http.Request, account, accountKey string) (string, error)
- func StringToSign(r *http.Request, account string) string
- func StringToSignLite(r *http.Request, account string) string
- func VerifySharedKey(accountKey string, r *http.Request) (bool, error)
- type Authorization
- type Scheme
Constants ¶
const ( // DefaultAccountName is Azurite's fixed development storage account name. DefaultAccountName = "devstoreaccount1" // DefaultAccountKey is Azurite's fixed, publicly published development // storage account key (base64-encoded). DefaultAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" )
Azurite well-known development storage account. Real Azure SDKs configured with UseDevelopmentStorage=true, or an explicit connection string naming this account, sign requests with this fixed key — this is the same "fixed public dev secret" model Azurite itself uses, and lets gopherstack accept unmodified Azurite-targeting client configuration out of the box.
Variables ¶
var ErrMalformedAuthorization = errors.New("azureauth: malformed Authorization header")
ErrMalformedAuthorization is returned by VerifySharedKey when the request's Authorization header cannot be parsed as SharedKey or SharedKeyLite.
Functions ¶
func CanonicalizedHeaders ¶
CanonicalizedHeaders returns the canonicalized x-ms-* header block: every x-ms-* header, lowercased and sorted lexicographically by name, each rendered as "name:value\n" with whitespace trimmed and internal whitespace runs collapsed to a single space. Multiple values for the same header are comma-joined in the order net/http returns them.
func CanonicalizedResource ¶
CanonicalizedResource returns the canonicalized resource string for a request against account: "/<account><path>" followed by each query parameter, lowercased and sorted by name, rendered as "\nname:value" with repeated-parameter values comma-joined after sorting.
gopherstack, like Azurite, serves path-style requests whose URL already starts with "/<account>/..." (real Azure serves the account as a subdomain instead, so the URL path never contains it). Real SDKs know which style they're signing for and build the canonicalized resource as "/<account>" plus the resource path with any such account segment removed, so that a path-style request and an equivalent subdomain-style request sign identically; this strips a leading "/<account>" path segment before applying that formula so signatures computed here match what an Azurite-targeting SDK actually sends.
func SignSharedKey ¶
SignSharedKey computes the SharedKey signature for r as account, using accountKey (base64-encoded, e.g. DefaultAccountKey). It does not modify r or set the Authorization header; callers that want a signed request do that themselves with the returned signature.
func SignSharedKeyLite ¶
SignSharedKeyLite computes the SharedKeyLite signature for r as account, using accountKey (base64-encoded).
func StringToSign ¶
StringToSign builds the SharedKey string-to-sign for r, canonicalized against the given storage account name, per Microsoft's "Authorize with Shared Key" REST reference:
VERB + "\n" + Content-Encoding + "\n" + Content-Language + "\n" + Content-Length + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + If-Modified-Since + "\n" + If-Match + "\n" + If-None-Match + "\n" + If-Unmodified-Since + "\n" + Range + "\n" + CanonicalizedHeaders + CanonicalizedResource
func StringToSignLite ¶
StringToSignLite builds the SharedKeyLite string-to-sign for r:
VERB + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedHeaders + CanonicalizedResource
func VerifySharedKey ¶
VerifySharedKey recomputes the SharedKey or SharedKeyLite signature for r (dispatching on the scheme named in its Authorization header) using accountKey, and reports whether it matches the signature the client sent.
This is an explicit, opt-in check: nothing in this package calls it implicitly, and ParseAuthorizationHeader never fails or reports a mismatch on its own — callers that want enforcement invoke VerifySharedKey themselves, mirroring services/s3's opt-in WithPresignValidation pattern. It returns (ErrMalformedAuthorization) wrapped in the error when the header can't be parsed at all.
Types ¶
type Authorization ¶
type Authorization struct {
// Account is the storage account name that signed the request.
Account string
// Signature is the base64-encoded HMAC-SHA256 signature the client sent.
Signature string
// Scheme is which of SharedKey / SharedKeyLite was used.
Scheme Scheme
}
Authorization is the parsed form of an Azure Storage Authorization header: "SharedKey <account>:<signature>" or "SharedKeyLite <account>:<signature>".
func ParseAuthorizationHeader ¶
func ParseAuthorizationHeader(header string) (Authorization, bool)
ParseAuthorizationHeader parses the value of an Authorization header carrying a SharedKey or SharedKeyLite credential. The bool return is false when the header is empty, uses an unrecognised scheme, or is missing the account name or signature — it never inspects or validates the signature itself, so a structurally well-formed header with a wrong signature still parses successfully. Use VerifySharedKey to check the signature.