Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
906 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
appname = cyber-auth-api | ||
httpport = 8086 | ||
runmode = dev | ||
autorender = false | ||
copyrequestbody = true | ||
EnableDocs = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 == "*") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() | ||
} | ||
} |
Oops, something went wrong.