mirror of
https://github.com/alibaba/higress.git
synced 2026-02-23 12:10:53 +08:00
147 lines
3.6 KiB
Go
147 lines
3.6 KiB
Go
// 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, ";")
|
||
}
|