HyperLeger Fabric SDK開發(八)——msp
HyperLeger Fabric SDK開發(八)——msp
一、msp簡介
1、msp簡介
msp支援在Fabric網路上建立和更新使用者。MSP客戶端支援以下操作:Enroll,Reenroll,Register,Revoke和GetSigningIdentity。
官方文件:
https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp
2、msp使用流程
msp使用的基本流程如下:
A、準備客戶端上下文
B、建立msp客戶端
C、註冊使用者
D、註冊使用者
使用示例:
ctx := mockClientProvider() // Create msp client c, err := New(ctx) if err != nil { fmt.Println("failed to create msp client") return } username := randomUsername() enrollmentSecret, err := c.Register(&RegistrationRequest{Name: username}) if err != nil { fmt.Printf("Register return error %s\n", err) return } err = c.Enroll(username, WithSecret(enrollmentSecret)) if err != nil { fmt.Printf("failed to enroll user: %s\n", err) return } fmt.Println("enroll user is completed") // output: // enroll user is completed
二、msp常用介面
1、型別定義
var (
// ErrUserNotFound indicates the user was not found
ErrUserNotFound = errors.New("user not found")
)
type AffiliationInfo struct {
Name string
Affiliations []AffiliationInfo
Identities []IdentityInfo
}
AffiliationInfo包含附屬資訊名稱,子附屬資訊,以及本附屬相關的身份標識
type AffiliationRequest struct { // 附屬名稱 Name string // Creates parent affiliations if they do not exist Force bool // CA名稱 CAName string }
AffiliationRequest表示要增加或刪除附屬資訊到CA伺服器的請求
type AffiliationResponse struct {
AffiliationInfo
CAName string
}
AffiliationResponse包含獲取、增加、修改、刪除一個附屬資訊的響應
type Attribute struct {
Name string
Value string
ECert bool
}
Attribute定義了要傳遞給註冊物件的附加屬性
type AttributeRequest struct { Name string Optional bool }
AttributeRequest定義一個屬性的請求
// IdentityManager provides management of identities in a Fabric network
type IdentityManager interface {
GetSigningIdentity(name string) (msp.SigningIdentity, error)
CreateSigningIdentity(ops ...msp.SigningIdentityOption) (msp.SigningIdentity, error)
}
// RegistrationRequest defines the attributes required to register a user with the CA
type RegistrationRequest struct {
// Name is the unique name of the identity
Name string
// Type of identity being registered (e.g. "peer, app, user")
Type string
// MaxEnrollments is the number of times the secret can be reused to enroll.
// if omitted, this defaults to max_enrollments configured on the server
MaxEnrollments int
// The identity's affiliation e.g. org1.department1
Affiliation string
// Optional attributes associated with this identity
Attributes []Attribute
// CAName is the name of the CA to connect to
CAName string
// Secret is an optional password. If not specified,
// a random secret is generated. In both cases, the secret
// is returned from registration.
Secret string
}
// IdentityRequest represents the request to add/update identity to the fabric-ca-server
type IdentityRequest struct {
// The enrollment ID which uniquely identifies an identity (required)
ID string
// The identity's affiliation (required)
Affiliation string
// Array of attributes to assign to the user
Attributes []Attribute
// Type of identity being registered (e.g. 'peer, app, user'). Default is 'user'.
Type string
// The maximum number of times the secret can be reused to enroll (default CA's Max Enrollment)
MaxEnrollments int
// The enrollment secret. If not provided, a random secret is generated.
Secret string
// Name of the CA to send the request to within the Fabric CA server (optional)
CAName string
}
// IdentityResponse is the response from the any read/add/modify/remove identity call
type IdentityResponse struct {
// The enrollment ID which uniquely identifies an identity
ID string
// The identity's affiliation
Affiliation string
// Array of attributes assigned to the user
Attributes []Attribute
// Type of identity (e.g. 'peer, app, user')
Type string
// The maximum number of times the secret can be reused to enroll
MaxEnrollments int
// The enrollment secret
Secret string
// Name of the CA
CAName string
}
type RemoveIdentityRequest struct {
// The enrollment ID which uniquely identifies an identity
ID string
// Force delete
Force bool
// Name of the CA
CAName string
}
// RevocationRequest defines the attributes required to revoke credentials with the CA
type RevocationRequest struct {
// Name of the identity whose certificates should be revoked
// If this field is omitted, then Serial and AKI must be specified.
Name string
// Serial number of the certificate to be revoked
// If this is omitted, then Name must be specified
Serial string
// AKI (Authority Key Identifier) of the certificate to be revoked
AKI string
// Reason is the reason for revocation. See https://godoc.org/golang.org/x/crypto/ocsp
// for valid values. The default value is 0 (ocsp.Unspecified).
Reason string
// CAName is the name of the CA to connect to
CAName string
}
// RevocationResponse represents response from the server for a revocation request
type RevocationResponse struct {
// RevokedCerts is an array of certificates that were revoked
RevokedCerts []RevokedCert
// CRL is PEM-encoded certificate revocation list (CRL) that contains all unexpired revoked certificates
CRL []byte
}
// RevokedCert represents a revoked certificate
type RevokedCert struct {
// Serial number of the revoked certificate
Serial string
// AKI of the revoked certificate
AKI string
}
2、獲取客戶端例項
type Client struct {
orgName string
caName string
ctx context.Client
}
func New(clientProvider context.ClientProvider, opts ...ClientOption) (*Client, error)
New建立一個新的Client例項
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
if c != nil {
fmt.Println("msp client created")
}
// output:
// msp client created
3、建立身份標識
func (c *Client) CreateIdentity(request *IdentityRequest) (*IdentityResponse, error)
CreateIdentity使用Fabric CA伺服器建立一個新身份標識。 返回的登記secret與登記ID一起使用可以登記新身份。
引數:
請求包含身份相關資訊
返回包含secret的身份資訊
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
identity, err := c.CreateIdentity(&IdentityRequest{ID: "123", Affiliation: "org2",
Attributes: []Attribute{{Name: "attName1", Value: "attValue1"}}})
if err != nil {
fmt.Printf("Create identity return error %s\n", err)
return
}
fmt.Printf("identity '%s' created\n", identity.ID)
// output:
// identity '123' created
4、建立簽名的身份標識
func (c *Client) CreateSigningIdentity(opts ...mspctx.SigningIdentityOption) (mspctx.SigningIdentity, error)
CreateSigningIdentity使用給定選項建立一個簽名標識。
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
testPrivKey := `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgp4qKKB0WCEfx7XiB
5Ul+GpjM1P5rqc6RhjD5OkTgl5OhRANCAATyFT0voXX7cA4PPtNstWleaTpwjvbS
J3+tMGTG67f+TdCfDxWYMpQYxLlE8VkbEzKWDwCYvDZRMKCQfv2ErNvb
-----END PRIVATE KEY-----`
testCert := `-----BEGIN CERTIFICATE-----
MIICGTCCAcCgAwIBAgIRALR/1GXtEud5GQL2CZykkOkwCgYIKoZIzj0EAwIwczEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh
Lm9yZzEuZXhhbXBsZS5jb20wHhcNMTcwNzI4MTQyNzIwWhcNMjcwNzI2MTQyNzIw
WjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN
U2FuIEZyYW5jaXNjbzEfMB0GA1UEAwwWVXNlcjFAb3JnMS5leGFtcGxlLmNvbTBZ
MBMGByqGSM49AgEGCCqGSM49AwEHA0IABPIVPS+hdftwDg8+02y1aV5pOnCO9tIn
f60wZMbrt/5N0J8PFZgylBjEuUTxWRsTMpYPAJi8NlEwoJB+/YSs29ujTTBLMA4G
A1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIIeR0TY+iVFf
mvoEKwaToscEu43ZXSj5fTVJornjxDUtMAoGCCqGSM49BAMCA0cAMEQCID+dZ7H5
AiaiI2BjxnL3/TetJ8iFJYZyWvK//an13WV/AiARBJd/pI5A7KZgQxJhXmmR8bie
XdsmTcdRvJ3TS/6HCA==
-----END CERTIFICATE-----`
// Create signing identity based on certificate and private key
id, err := c.CreateSigningIdentity(msp.WithCert([]byte(testCert)), msp.WithPrivateKey([]byte(testPrivKey)))
if err != nil {
fmt.Printf("failed when creating identity based on certificate and private key: %s\n", err)
return
}
if string(id.EnrollmentCertificate()) != testCert {
fmt.Printf("certificate mismatch\n")
return
}
// In this user case client might want to import keys directly into keystore
// out of band instead of enrolling the user via SDK. User enrolment creates a cert
// and stores it into local SDK user store, while user might not want SDK to manage certs.
err = importPrivateKeyOutOfBand([]byte(testPrivKey), c)
if err != nil {
fmt.Printf("failed to import key: %s\n", err)
return
}
// Create signing identity using certificate. SDK will lookup the private key based on the certificate.
id, err = c.CreateSigningIdentity(msp.WithCert([]byte(testCert)))
if err != nil {
fmt.Printf("failed when creating identity using certificate: %s\n", err)
return
}
if string(id.EnrollmentCertificate()) != testCert {
fmt.Printf("certificate mismatch\n")
return
}
fmt.Println("create signing identity is completed")
// output:
// create signing identity is completed
5、登記使用者
func (c *Client) Enroll(enrollmentID string, opts ...EnrollmentOption) error
登記使用者以便接收簽名的X509證書。為使用者生成新的金鑰對。私鑰和登記證書由CA頒發,儲存在SDK資料庫中。可以通過呼叫IdentityManager.GetSigningIdentity()來檢索它們。
引數:
enrollmentID登記使用者的登記ID
opts是可選的登記選項
如果登記失敗,則返回出錯資訊
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
6、檢視身份
func (c *Client) GetAllIdentities(options ...RequestOption) ([]*IdentityResponse, error)
GetAllIdentities返回呼叫者有權檢視的所有身份
引數:
options包含可選的請求選項
返回包含身份的響應
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
results, err := c.GetAllIdentities()
if err != nil {
fmt.Printf("Get identities return error %s\n", err)
return
}
fmt.Printf("%d identities retrieved\n", len(results))
// output:
// 2 identities retrieved
7、檢視身份資訊
func (c *Client) GetIdentity(ID string, options ...RequestOption) (*IdentityResponse, error)
GetIdentity檢索身份資訊
引數:
ID是必需的身份ID
options包含可選的請求選項
返回包含身份資訊的響應
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
identity, err := c.GetIdentity("123")
if err != nil {
fmt.Printf("Get identity return error %s\n", err)
return
}
fmt.Printf("identity '%s' retrieved\n", identity.ID)
// output:
// identity '123' retrieved
8、獲取簽名身份
func (c *Client) GetSigningIdentity(id string) (mspctx.SigningIdentity, error)
GetSigningIdentity返回身份id的簽名身份
引數:
id是使用者ID
返回簽名身份
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
username := randomUsername()
err = c.Enroll(username, WithSecret("enrollmentSecret"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
enrolledUser, err := c.GetSigningIdentity(username)
if err != nil {
fmt.Printf("user not found %s\n", err)
return
}
if enrolledUser.Identifier().ID != username {
fmt.Println("Enrolled user name doesn't match")
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
9、修改身份
func (c *Client) ModifyIdentity(request *IdentityRequest) (*IdentityResponse, error)
ModifyIdentity使用Fabric CA伺服器修改身份
引數:
request包含有關身份的資訊
返回更新的身份資訊
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
identity, err := c.ModifyIdentity(&IdentityRequest{ID: "123", Affiliation: "org2", Secret: "top-secret"})
if err != nil {
fmt.Printf("Modify identity return error %s\n", err)
return
}
fmt.Printf("identity '%s' modified\n", identity.ID)
// output:
// identity '123' modified
10、重新登記使用者
func (c *Client) Reenroll(enrollmentID string, opts ...EnrollmentOption) error
重新登記一個已登記使用者,以便獲得一個新的簽名X509證書
引數:
enrollmentID是註冊使用者的登記ID
如果重新登記失敗,返回出錯資訊。
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
username := randomUsername()
err = c.Enroll(username, WithSecret("enrollmentSecret"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
err = c.Reenroll(username)
if err != nil {
fmt.Printf("failed to reenroll user: %s\n", err)
return
}
fmt.Println("reenroll user is completed")
// output:
// reenroll user is completed
11、註冊使用者
func (c *Client) Register(request *RegistrationRequest) (string, error)
使用Fabric CA註冊一個使用者
引數:
request是註冊請求
返回登記secret
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
_, err = c.Register(&RegistrationRequest{Name: randomUsername()})
if err != nil {
fmt.Printf("Register return error %s\n", err)
return
}
fmt.Println("register user is completed")
// output:
// register user is completed
12、刪除身份標識
func (c *Client) RemoveIdentity(request *RemoveIdentityRequest) (*IdentityResponse, error)
RemoveIdentity使用Fabric CA伺服器刪除身份標識。
引數:
request是包含要刪除的身份的資訊
返回已刪除的身份資訊
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
identity, err := c.RemoveIdentity(&RemoveIdentityRequest{ID: "123"})
if err != nil {
fmt.Printf("Remove identity return error %s\n", err)
return
}
fmt.Printf("identity '%s' removed\n", identity.ID)
// output:
// identity '123' removed
13、撤銷使用者
func (c *Client) Revoke(request *RevocationRequest) (*RevocationResponse, error)
使用Fabric CA的撤銷一個使用者
引數:
request是撤銷請求
返回撤銷響應
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
_, err = c.Revoke(&RevocationRequest{Name: "testuser"})
if err != nil {
fmt.Printf("revoke return error %s\n", err)
}
fmt.Println("revoke user is completed")
// output:
// revoke user is completed
14、選項構建
type ClientOption func(*Client) error
// WithOrg option
func WithOrg(orgName string) ClientOption
返回包含組織的ClientOption,作為引數
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx, WithOrg("org1"))
if err != nil {
fmt.Println("failed to create msp client")
return
}
if c != nil {
fmt.Println("msp client created with org")
}
// output:
// msp client created with org
type enrollmentOptions struct {
secret string
profile string
label string
typ string
attrReqs []*AttributeRequest
}
// EnrollmentOption describes a functional parameter for Enroll
type EnrollmentOption func(*enrollmentOptions) error
// WithSecret enrollment option
func WithSecret(secret string) EnrollmentOption
使用secret引數,返回EnrollmentOption,作為登記的選項
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
type requestOptions struct {
CA string
}
// RequestOption func for each Opts argument
type RequestOption func(ctx context.Client, opts *requestOptions) error
// WithCA allows for specifying optional CA name
func WithCA(caname string) RequestOption
根據CA名稱返回RequestOption
使用示例:
// Create msp client
c, err := New(mockClientProvider())
if err != nil {
fmt.Println("failed to create msp client")
return
}
results, err := c.GetAllIdentities(WithCA("CA"))
if err != nil {
fmt.Printf("Get identities return error %s\n", err)
return
}
fmt.Printf("%d identities retrieved\n", len(results))
// output:
// 2 identities retrieved
func WithType(typ string) EnrollmentOption
根據證書型別typ引數返回EnrollmentOption
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithType("x509") /*or idemix, which is not support now*/)
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
func WithProfile(profile string) EnrollmentOption
使用profile返回一個EnrollmentOption
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithProfile("tls"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
func WithLabel(label string) EnrollmentOption
使用label引數返回EnrollmentOption
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithLabel("ForFabric"))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed
func WithAttributeRequests(attrReqs []*AttributeRequest) EnrollmentOption
使用屬性請求引數attrReqs返回EnrollmentOption
使用示例:
ctx := mockClientProvider()
// Create msp client
c, err := New(ctx)
if err != nil {
fmt.Println("failed to create msp client")
return
}
attrs := []*AttributeRequest{{Name: "name1", Optional: true}, {Name: "name2", Optional: true}}
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithAttributeRequests(attrs))
if err != nil {
fmt.Printf("failed to enroll user: %s\n", err)
return
}
fmt.Println("enroll user is completed")
// output:
// enroll user is completed