A simple example of go in + caspin RBAC

Explain

//Libraries used:
github.com/casbin/casbin
github.com/gin-gonic/gin
github.com/facebookgo/inject
This article is for reference: https://github.com/LyricTian/gin-admin, highly recommended!!!

Caspin document: https://caspin.org/zh-cn/

The following example does not use the adapter of caspin, but initializes it first when starting,
Then through the corresponding relationship in the database, dynamically load all permission entries

Then through the middleware to judge, if there is an update, you can dynamically modify the update permission entry

Example

Catalog

Code

rbac_model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) == true \
    && keyMatch2(r.obj, p.obj) == true \
    && regexMatch(r.act, p.act) == true 
b_auth.go 

package bll

//In allin / models is your own project, please ignore
import (
   "gin-allin/models"
   "github.com/casbin/casbin"
)

//models.Auth can actually write its own User table for the User table  
type Role struct {
   Role      *models.Auth     `inject:""`
   Enforcer  *casbin.Enforcer `inject:""`
}

// LoadPolicy load role permission policy,
func (a *Role) LoadPolicy(roleID string) error {
   a.Enforcer.AddPolicy(roleID, "/api/v1/auth_info","GET")
   return nil
}
b_common.go

package bll

//Inject permission table into Common
type Common struct {
   Role   *Role    `inject:""`
}

inject.go
package inject

import (
   "gin-allin/bll"
   "github.com/casbin/casbin"
   "github.com/facebookgo/inject"
   "os"
)

// Object injection object  
type Object struct {
   Common     *bll.Common
   Enforcer   *casbin.Enforcer
}

// Init initialize dependency injection
func Init() *Object {
   g := new(inject.Graph)

   // Injecting casbin    
   dir, _ := os.Getwd()
   path := dir + "\\src\\gin-allin\\conf\\rbac_model.conf"
   enforcer := casbin.NewEnforcer(path, false)
   _ = g.Provide(&inject.Object{Value: enforcer})

   //  Inject Common, or Role
   Common := new(bll.Common)
   _ = g.Provide(&inject.Object{Value: Common})

   if err := g.Populate(); err != nil {
      panic("Error initializing dependency injection:" + err.Error())
   }

   // Return the injected object 
   return &Object{
      Enforcer:  enforcer,
      Common :Common,
   }
}
casb.go

package casb

import (
   "gin-allin/inject"
   "github.com/gin-gonic/gin"
   "net/http"
)

// Authority judgement   
func CasbinMiddleware(obj *inject.Object) gin.HandlerFunc {
   return func(c *gin.Context) {

      // Judge whether the permission is true
      if b, err := obj.Enforcer.EnforceSafe("hequan", c.Request.URL.Path, c.Request.Method); err != nil {
         c.JSON(http.StatusUnauthorized, gin.H{
            "code": "Wrong authority judgment",
            "msg":  "Wrong authority judgment",
            "data": "Wrong authority judgment",
         })
         c.Abort()
         return
      } else if !b {

         c.JSON(http.StatusUnauthorized, gin.H{
            "code": "No authority",
            "msg":  "No authority",
            "data": "No authority",
         })
         c.Abort()
         return
      }
      c.Next()
   }
}
router.go

package routers

func InitRouter() *gin.Engine {
   // Generated object
   obj := inject.Init()

   err := loadCasbinPolicyData(obj)

   if err != nil {
      panic("Load casbin Error in policy data:" + err.Error())
   }

   apiv1.Use(casb.CasbinMiddleware(obj))
}

// Load the policy data of casbin load a permission of hequan
func loadCasbinPolicyData(obj *inject.Object) error {
   err := obj.Common.Role.LoadPolicy("hequan")
   if err != nil {
      fmt.Println(err)
      return err
   }
   return nil
}

Result

When the user hequan accesses / api/v1/auth_info, he will judge whether he has GET permission. If yes, he will pass, if not, he will refuse.

The test can write other user names and restart them. At this time, if the middleware fails to pass the judgment, it will return to reject.

Tags: Go github JSON Database

Posted on Wed, 04 Dec 2019 15:59:07 -0500 by derekbelcher