mirror of
https://github.com/alibaba/higress.git
synced 2026-06-07 03:37:28 +08:00
feat(plugin): implement golang version of plugin jwt-auth (#743)
Signed-off-by: Ink33 <Ink33@smlk.org>
This commit is contained in:
146
plugins/wasm-go/extensions/jwt-auth/handler/extractor.go
Normal file
146
plugins/wasm-go/extensions/jwt-auth/handler/extractor.go
Normal file
@@ -0,0 +1,146 @@
|
||||
// Copyright (c) 2023 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// 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 handler
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
cfg "github.com/alibaba/higress/plugins/wasm-go/extensions/jwt-auth/config"
|
||||
)
|
||||
|
||||
// extracToken 从三个来源中依次尝试抽取Token,若找不到Token则返回空字符串
|
||||
func extractToken(keepToken bool, consumer *cfg.Consumer, header HeaderProvider, log Logger) string {
|
||||
token := ""
|
||||
|
||||
// 1. 从header中抽取token
|
||||
if h := consumer.FromHeaders; h != nil {
|
||||
token = extractFromHeader(keepToken, *h, header, log)
|
||||
}
|
||||
if token != "" {
|
||||
return token
|
||||
}
|
||||
|
||||
// 2. 从params中抽取token
|
||||
if p := consumer.FromParams; p != nil {
|
||||
token = extractFromParams(keepToken, *p, header, log)
|
||||
}
|
||||
if token != "" {
|
||||
return token
|
||||
}
|
||||
|
||||
// 3. 从cookies中抽取token
|
||||
if c := consumer.FromCookies; c != nil {
|
||||
token = extractFromCookies(keepToken, *c, header, log)
|
||||
}
|
||||
|
||||
// 此处无需判空
|
||||
return token
|
||||
}
|
||||
|
||||
func extractFromHeader(keepToken bool, headers []cfg.FromHeader, header HeaderProvider, log Logger) (token string) {
|
||||
for i := range headers {
|
||||
|
||||
// proxywasm 获取到的 header name 均为小写,此处需做修改
|
||||
lowerName := strings.ToLower(headers[i].Name)
|
||||
token, err := header.GetHttpRequestHeader(lowerName)
|
||||
if err != nil {
|
||||
log.Warnf("failed to get authorization: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if token != "" {
|
||||
if !strings.HasPrefix(token, headers[i].ValuePrefix) {
|
||||
log.Warnf("authorization has no prefix %q", headers[i].ValuePrefix)
|
||||
return ""
|
||||
}
|
||||
if !keepToken {
|
||||
_ = header.RemoveHttpRequestHeader(lowerName)
|
||||
}
|
||||
return strings.TrimPrefix(token, headers[i].ValuePrefix)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func extractFromParams(keepToken bool, params []string, header HeaderProvider, log Logger) (token string) {
|
||||
urlparams, err := header.GetHttpRequestHeader(":path")
|
||||
if err != nil {
|
||||
log.Warnf("failed to get authorization: %v", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
url, _ := url.Parse(urlparams)
|
||||
query := url.Query()
|
||||
|
||||
for i := range params {
|
||||
token := query.Get(params[i])
|
||||
if token != "" {
|
||||
if !keepToken {
|
||||
query.Del(params[i])
|
||||
}
|
||||
return token
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func extractFromCookies(keepToken bool, cookies []string, header HeaderProvider, log Logger) (token string) {
|
||||
requestCookies, err := header.GetHttpRequestHeader("cookie")
|
||||
if err != nil {
|
||||
log.Warnf("failed to get authorization: %v", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
for i := range cookies {
|
||||
token := findCookie(requestCookies, cookies[i])
|
||||
if token != "" {
|
||||
if !keepToken {
|
||||
_ = header.ReplaceHttpRequestHeader("cookie", deleteCookie(requestCookies, cookies[i]))
|
||||
}
|
||||
return token
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func findCookie(cookie string, key string) string {
|
||||
value := ""
|
||||
pairs := strings.Split(cookie, ";")
|
||||
|
||||
for _, pair := range pairs {
|
||||
pair = strings.TrimSpace(pair)
|
||||
kv := strings.Split(pair, "=")
|
||||
if kv[0] == key {
|
||||
value = kv[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
func deleteCookie(cookie string, key string) string {
|
||||
result := ""
|
||||
pairs := strings.Split(cookie, ";")
|
||||
|
||||
for _, pair := range pairs {
|
||||
pair = strings.TrimSpace(pair)
|
||||
if !strings.HasPrefix(pair, key) {
|
||||
result += pair + ";"
|
||||
}
|
||||
}
|
||||
return strings.TrimSuffix(result, ";")
|
||||
}
|
||||
Reference in New Issue
Block a user