Skip to content

Commit

Permalink
init project
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasZh committed Dec 7, 2017
1 parent 8fd778e commit aa64db8
Show file tree
Hide file tree
Showing 20 changed files with 906 additions and 1 deletion.
29 changes: 28 additions & 1 deletion README.md
@@ -1 +1,28 @@
# cyber-auth-api
# cyber-auth-api

''# yum install go

$ vi ~/.bashrc
export GOROOT=/usr/lib/golang
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin


$ go get github.com/astaxie/beego
$ go get github.com/beego/bee


$ bee api cyber-auth-api
$ cd cyber-auth-api/
$ bee run -gendoc=true -downdoc=true


$ go get -u github.com/go-sql-driver/mysql
$ go get github.com/satori/go.uuid
$ go get gopkg.in/mgo.v2
$ go get github.com/bradfitz/gomemcache/memcache
$ go get github.com/casbin/casbin


# Linux下通过端口查看进程
''# netstat -anp|grep 8086
107 changes: 107 additions & 0 deletions auth/auth.go
@@ -0,0 +1,107 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package auth provides handlers to enable basic auth support.
// Simple Usage:
// import(
// "github.com/astaxie/beego"
// "github.com/astaxie/beego/plugins/auth"
// )
//
// func main(){
// // authenticate every request
// beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword"))
// beego.Run()
// }
//
//
// Advanced Usage:
//
// func SecretAuth(username, password string) bool {
// return username == "astaxie" && password == "helloBeego"
// }
// authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required")
// beego.InsertFilter("*", beego.BeforeRouter,authPlugin)
package auth

import (
"encoding/base64"
"net/http"
"strings"

"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
)

var defaultRealm = "Authorization Required"

// Basic is the http basic auth
func Basic(username string, password string) beego.FilterFunc {
secrets := func(user, pass string) bool {
return user == username && pass == password
}
return NewBasicAuthenticator(secrets, defaultRealm)
}

// NewBasicAuthenticator return the BasicAuth
func NewBasicAuthenticator(secrets SecretProvider, Realm string) beego.FilterFunc {
return func(ctx *context.Context) {
a := &BasicAuth{Secrets: secrets, Realm: Realm}
if username := a.CheckAuth(ctx.Request); username == "" {
a.RequireAuth(ctx.ResponseWriter, ctx.Request)
}
}
}

// SecretProvider is the SecretProvider function
type SecretProvider func(user, pass string) bool

// BasicAuth store the SecretProvider and Realm
type BasicAuth struct {
Secrets SecretProvider
Realm string
}

// CheckAuth Checks the username/password combination from the request. Returns
// either an empty string (authentication failed) or the name of the
// authenticated user.
// Supports MD5 and SHA1 password entries
func (a *BasicAuth) CheckAuth(r *http.Request) string {
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
if len(s) != 2 || s[0] != "Basic" {
return "guest"
}

b, err := base64.StdEncoding.DecodeString(s[1])
if err != nil {
return "guest"
}
pair := strings.SplitN(string(b), ":", 2)
if len(pair) != 2 {
return "guest"
}

if a.Secrets(pair[0], pair[1]) {
return pair[0]
}
return "guest"
}

// RequireAuth http.Handler for BasicAuth which initiates the authentication process
// (or requires reauthentication).
func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate", `Basic realm="`+a.Realm+`"`)
w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n"))
}
127 changes: 127 additions & 0 deletions authz/authz.go
@@ -0,0 +1,127 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package authz provides handlers to enable ACL, RBAC, ABAC authorization support.
// Simple Usage:
// import(
// "github.com/astaxie/beego"
// "github.com/astaxie/beego/plugins/authz"
// "github.com/casbin/casbin"
// )
//
// func main(){
// // mediate the access for every request
// beego.InsertFilter("*", beego.BeforeRouter, authz.NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv")))
// beego.Run()
// }
//
//
// Advanced Usage:
//
// func main(){
// e := casbin.NewEnforcer("authz_model.conf", "")
// e.AddRoleForUser("alice", "admin")
// e.AddPolicy(...)
//
// beego.InsertFilter("*", beego.BeforeRouter, authz.NewAuthorizer(e))
// beego.Run()
// }
package authz

import (
"net"
"net/http"
"encoding/base64"
"strings"
"fmt"

"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/casbin/casbin"

"cyber-auth-api/models"
)

// NewAuthorizer returns the authorizer.
// Use a casbin enforcer as input
func NewAuthorizer(e *casbin.Enforcer) beego.FilterFunc {
return func(ctx *context.Context) {
a := &BasicAuthorizer{enforcer: e}

if !a.CheckPermission(ctx.Request) {
a.RequirePermission(ctx.ResponseWriter)
}
}
}

// BasicAuthorizer stores the casbin handler
type BasicAuthorizer struct {
enforcer *casbin.Enforcer
}

// GetUserName gets the user name from the request.
// Currently, only HTTP basic authentication is supported
func (a *BasicAuthorizer) GetGroupName(r *http.Request) string {
// username, _, _ := r.BasicAuth()
// return username
// header={Authorization:"Bearer access_token"}
authorString := r.Header.Get("Authorization")
fmt.Println("Authorization:", authorString)
s := strings.SplitN(authorString, " ", 2)
if len(s) != 2 || s[0] != "Bearer" {
return "guest"
}

_, err := base64.StdEncoding.DecodeString(s[1])
if err != nil {
return "guest"
}

ticket := models.FindAccessToken(s[1])
if (ticket == nil) {
return "guest"
} else {
// TODO user, member, ops, admin
return "user"
}
}

// getIpAddress gets the remote addr from the request.
func getIPAddress(r *http.Request) (string, error) {
addr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr)
if err != nil {
return "", err
}
return addr.IP.String(), nil
}

// CheckPermission checks the user/method/path combination from the request.
// Returns true (permission granted) or false (permission forbidden)
func (a *BasicAuthorizer) CheckPermission(r *http.Request) bool {
user := a.GetGroupName(r)
fmt.Println("group:", user)
addr, err := getIPAddress(r)
if err != nil {
return false
}
method := r.Method
path := r.URL.Path
return a.enforcer.Enforce(user, addr, path, method)
}

// RequirePermission returns the 403 Forbidden to the client
func (a *BasicAuthorizer) RequirePermission(w http.ResponseWriter) {
w.WriteHeader(403)
w.Write([]byte("403 Forbidden\n"))
}
6 changes: 6 additions & 0 deletions conf/app.conf
@@ -0,0 +1,6 @@
appname = cyber-auth-api
httpport = 8086
runmode = dev
autorender = false
copyrequestbody = true
EnableDocs = true
14 changes: 14 additions & 0 deletions conf/authz_model.conf
@@ -0,0 +1,14 @@
[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && ipMatch(r.dom, p.dom) && keyMatch(r.obj, p.obj) && (r.act == p.act || p.act == "*")
5 changes: 5 additions & 0 deletions conf/authz_policy.csv
@@ -0,0 +1,5 @@
p, guest, 0.0.0.0/0, /swagger/, GET
p, user, 0.0.0.0/0, /swagger/, GET
p, guest, 0.0.0.0/0, /api/auth/login/, POST
p, user, 0.0.0.0/0, /api/auth/login/, POST
p, user, 0.0.0.0/0, /api/auth/ticket/*, GET
88 changes: 88 additions & 0 deletions controllers/auth_login.go
@@ -0,0 +1,88 @@
package controllers

import (
"cyber-auth-api/models"
"encoding/json"
"github.com/astaxie/beego"
"log"
"fmt"
"net/rpc"
)


// Operations about Login
type LoginController struct {
beego.Controller
}

var GlobalRpcClient *rpc.Client
var err error

func init() {
service := "127.0.0.1:12345"
client, err := rpc.Dial("tcp", service)
if err != nil {
log.Fatal("dialing:", err)
}
GlobalRpcClient = client
}


// @Title Login
// @Description login by username & password though RPC
// @Param body body models.LoginReq true "body for login content"
// @Success 200 {object} models.SessionTicket
// @Failure 403 :username or password is empty
// @router / [post]
func (this *LoginController) Post() {
uri := this.Ctx.Input.URI()
beego.Info(uri)
beego.Info(this.Ctx.Input.RequestBody)

var req models.LoginReq
json.Unmarshal(this.Ctx.Input.RequestBody, &req)
beego.Trace(req)
if (req.Username == "" || req.Password == "") {
var rs = &models.LoginResp{
Code: 403,
Msg: "Bad Request",
}

this.Data["json"] = *rs
this.ServeJSON()
return
}

// only for test, unit test can't md5(password) by js
var args = &models.CreateTicketArgs{
Username: req.Username,
Md5Password: models.GetMd5String(req.Password),
}
reply := &models.SessionTicket{}
err = GlobalRpcClient.Call("Mgo.CreateTicket", args, &reply)
if err != nil {
log.Fatal("CreateTicket error :", err)
}
fmt.Println("CreateTicket:", args, reply)

if (reply == nil || reply.Id == "") {
var rs = &models.LoginResp{
Code: 404,
Msg: "Not Found",
}

this.Data["json"] = *rs
this.ServeJSON()
} else {
beego.Trace(reply)

var rs = &models.LoginResp{
Code: 200,
Msg: "Success",
Rs: *reply,
}

this.Data["json"] = *rs
this.ServeJSON()
}
}

0 comments on commit aa64db8

Please sign in to comment.