mirror of
https://github.com/fatedier/frp.git
synced 2025-07-27 07:35:07 +00:00
@@ -19,101 +19,58 @@ import (
|
||||
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
|
||||
"github.com/vaughan0/go-ini"
|
||||
)
|
||||
|
||||
type baseConfig struct {
|
||||
type BaseConfig struct {
|
||||
// AuthenticationMethod specifies what authentication method to use to
|
||||
// authenticate frpc with frps. If "token" is specified - token will be
|
||||
// read into login message. If "oidc" is specified - OIDC (Open ID Connect)
|
||||
// token will be issued using OIDC settings. By default, this value is "token".
|
||||
AuthenticationMethod string `json:"authentication_method"`
|
||||
AuthenticationMethod string `ini:"authentication_method" json:"authentication_method"`
|
||||
// AuthenticateHeartBeats specifies whether to include authentication token in
|
||||
// heartbeats sent to frps. By default, this value is false.
|
||||
AuthenticateHeartBeats bool `json:"authenticate_heartbeats"`
|
||||
AuthenticateHeartBeats bool `ini:"authenticate_heartbeats" json:"authenticate_heartbeats"`
|
||||
// AuthenticateNewWorkConns specifies whether to include authentication token in
|
||||
// new work connections sent to frps. By default, this value is false.
|
||||
AuthenticateNewWorkConns bool `json:"authenticate_new_work_conns"`
|
||||
AuthenticateNewWorkConns bool `ini:"authenticate_new_work_conns" json:"authenticate_new_work_conns"`
|
||||
}
|
||||
|
||||
func getDefaultBaseConf() baseConfig {
|
||||
return baseConfig{
|
||||
func getDefaultBaseConf() BaseConfig {
|
||||
return BaseConfig{
|
||||
AuthenticationMethod: "token",
|
||||
AuthenticateHeartBeats: false,
|
||||
AuthenticateNewWorkConns: false,
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalBaseConfFromIni(conf ini.File) baseConfig {
|
||||
var (
|
||||
tmpStr string
|
||||
ok bool
|
||||
)
|
||||
|
||||
cfg := getDefaultBaseConf()
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "authentication_method"); ok {
|
||||
cfg.AuthenticationMethod = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "authenticate_heartbeats"); ok && tmpStr == "true" {
|
||||
cfg.AuthenticateHeartBeats = true
|
||||
} else {
|
||||
cfg.AuthenticateHeartBeats = false
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "authenticate_new_work_conns"); ok && tmpStr == "true" {
|
||||
cfg.AuthenticateNewWorkConns = true
|
||||
} else {
|
||||
cfg.AuthenticateNewWorkConns = false
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
baseConfig
|
||||
oidcClientConfig
|
||||
tokenConfig
|
||||
BaseConfig `ini:",extends"`
|
||||
OidcClientConfig `ini:",extends"`
|
||||
TokenConfig `ini:",extends"`
|
||||
}
|
||||
|
||||
func GetDefaultClientConf() ClientConfig {
|
||||
return ClientConfig{
|
||||
baseConfig: getDefaultBaseConf(),
|
||||
oidcClientConfig: getDefaultOidcClientConf(),
|
||||
tokenConfig: getDefaultTokenConf(),
|
||||
BaseConfig: getDefaultBaseConf(),
|
||||
OidcClientConfig: getDefaultOidcClientConf(),
|
||||
TokenConfig: getDefaultTokenConf(),
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalClientConfFromIni(conf ini.File) (cfg ClientConfig) {
|
||||
cfg.baseConfig = unmarshalBaseConfFromIni(conf)
|
||||
cfg.oidcClientConfig = unmarshalOidcClientConfFromIni(conf)
|
||||
cfg.tokenConfig = unmarshalTokenConfFromIni(conf)
|
||||
return cfg
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
baseConfig
|
||||
oidcServerConfig
|
||||
tokenConfig
|
||||
BaseConfig `ini:",extends"`
|
||||
OidcServerConfig `ini:",extends"`
|
||||
TokenConfig `ini:",extends"`
|
||||
}
|
||||
|
||||
func GetDefaultServerConf() ServerConfig {
|
||||
return ServerConfig{
|
||||
baseConfig: getDefaultBaseConf(),
|
||||
oidcServerConfig: getDefaultOidcServerConf(),
|
||||
tokenConfig: getDefaultTokenConf(),
|
||||
BaseConfig: getDefaultBaseConf(),
|
||||
OidcServerConfig: getDefaultOidcServerConf(),
|
||||
TokenConfig: getDefaultTokenConf(),
|
||||
}
|
||||
}
|
||||
|
||||
func UnmarshalServerConfFromIni(conf ini.File) (cfg ServerConfig) {
|
||||
cfg.baseConfig = unmarshalBaseConfFromIni(conf)
|
||||
cfg.oidcServerConfig = unmarshalOidcServerConfFromIni(conf)
|
||||
cfg.tokenConfig = unmarshalTokenConfFromIni(conf)
|
||||
return cfg
|
||||
}
|
||||
|
||||
type Setter interface {
|
||||
SetLogin(*msg.Login) error
|
||||
SetPing(*msg.Ping) error
|
||||
@@ -123,9 +80,9 @@ type Setter interface {
|
||||
func NewAuthSetter(cfg ClientConfig) (authProvider Setter) {
|
||||
switch cfg.AuthenticationMethod {
|
||||
case consts.TokenAuthMethod:
|
||||
authProvider = NewTokenAuth(cfg.baseConfig, cfg.tokenConfig)
|
||||
authProvider = NewTokenAuth(cfg.BaseConfig, cfg.TokenConfig)
|
||||
case consts.OidcAuthMethod:
|
||||
authProvider = NewOidcAuthSetter(cfg.baseConfig, cfg.oidcClientConfig)
|
||||
authProvider = NewOidcAuthSetter(cfg.BaseConfig, cfg.OidcClientConfig)
|
||||
default:
|
||||
panic(fmt.Sprintf("wrong authentication method: '%s'", cfg.AuthenticationMethod))
|
||||
}
|
||||
@@ -142,9 +99,9 @@ type Verifier interface {
|
||||
func NewAuthVerifier(cfg ServerConfig) (authVerifier Verifier) {
|
||||
switch cfg.AuthenticationMethod {
|
||||
case consts.TokenAuthMethod:
|
||||
authVerifier = NewTokenAuth(cfg.baseConfig, cfg.tokenConfig)
|
||||
authVerifier = NewTokenAuth(cfg.BaseConfig, cfg.TokenConfig)
|
||||
case consts.OidcAuthMethod:
|
||||
authVerifier = NewOidcAuthVerifier(cfg.baseConfig, cfg.oidcServerConfig)
|
||||
authVerifier = NewOidcAuthVerifier(cfg.BaseConfig, cfg.OidcServerConfig)
|
||||
}
|
||||
|
||||
return authVerifier
|
||||
|
@@ -21,30 +21,29 @@ import (
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
|
||||
"github.com/coreos/go-oidc"
|
||||
"github.com/vaughan0/go-ini"
|
||||
"golang.org/x/oauth2/clientcredentials"
|
||||
)
|
||||
|
||||
type oidcClientConfig struct {
|
||||
type OidcClientConfig struct {
|
||||
// OidcClientID specifies the client ID to use to get a token in OIDC
|
||||
// authentication if AuthenticationMethod == "oidc". By default, this value
|
||||
// is "".
|
||||
OidcClientID string `json:"oidc_client_id"`
|
||||
OidcClientID string `ini:"oidc_client_id" json:"oidc_client_id"`
|
||||
// OidcClientSecret specifies the client secret to use to get a token in OIDC
|
||||
// authentication if AuthenticationMethod == "oidc". By default, this value
|
||||
// is "".
|
||||
OidcClientSecret string `json:"oidc_client_secret"`
|
||||
OidcClientSecret string `ini:"oidc_client_secret" json:"oidc_client_secret"`
|
||||
// OidcAudience specifies the audience of the token in OIDC authentication
|
||||
//if AuthenticationMethod == "oidc". By default, this value is "".
|
||||
OidcAudience string `json:"oidc_audience"`
|
||||
OidcAudience string `ini:"oidc_audience" json:"oidc_audience"`
|
||||
// OidcTokenEndpointURL specifies the URL which implements OIDC Token Endpoint.
|
||||
// It will be used to get an OIDC token if AuthenticationMethod == "oidc".
|
||||
// By default, this value is "".
|
||||
OidcTokenEndpointURL string `json:"oidc_token_endpoint_url"`
|
||||
OidcTokenEndpointURL string `ini:"oidc_token_endpoint_url" json:"oidc_token_endpoint_url"`
|
||||
}
|
||||
|
||||
func getDefaultOidcClientConf() oidcClientConfig {
|
||||
return oidcClientConfig{
|
||||
func getDefaultOidcClientConf() OidcClientConfig {
|
||||
return OidcClientConfig{
|
||||
OidcClientID: "",
|
||||
OidcClientSecret: "",
|
||||
OidcAudience: "",
|
||||
@@ -52,56 +51,29 @@ func getDefaultOidcClientConf() oidcClientConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalOidcClientConfFromIni(conf ini.File) oidcClientConfig {
|
||||
var (
|
||||
tmpStr string
|
||||
ok bool
|
||||
)
|
||||
|
||||
cfg := getDefaultOidcClientConf()
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_client_id"); ok {
|
||||
cfg.OidcClientID = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_client_secret"); ok {
|
||||
cfg.OidcClientSecret = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_audience"); ok {
|
||||
cfg.OidcAudience = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_token_endpoint_url"); ok {
|
||||
cfg.OidcTokenEndpointURL = tmpStr
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type oidcServerConfig struct {
|
||||
type OidcServerConfig struct {
|
||||
// OidcIssuer specifies the issuer to verify OIDC tokens with. This issuer
|
||||
// will be used to load public keys to verify signature and will be compared
|
||||
// with the issuer claim in the OIDC token. It will be used if
|
||||
// AuthenticationMethod == "oidc". By default, this value is "".
|
||||
OidcIssuer string `json:"oidc_issuer"`
|
||||
OidcIssuer string `ini:"oidc_issuer" json:"oidc_issuer"`
|
||||
// OidcAudience specifies the audience OIDC tokens should contain when validated.
|
||||
// If this value is empty, audience ("client ID") verification will be skipped.
|
||||
// It will be used when AuthenticationMethod == "oidc". By default, this
|
||||
// value is "".
|
||||
OidcAudience string `json:"oidc_audience"`
|
||||
OidcAudience string `ini:"oidc_audience" json:"oidc_audience"`
|
||||
// OidcSkipExpiryCheck specifies whether to skip checking if the OIDC token is
|
||||
// expired. It will be used when AuthenticationMethod == "oidc". By default, this
|
||||
// value is false.
|
||||
OidcSkipExpiryCheck bool `json:"oidc_skip_expiry_check"`
|
||||
OidcSkipExpiryCheck bool `ini:"oidc_skip_expiry_check" json:"oidc_skip_expiry_check"`
|
||||
// OidcSkipIssuerCheck specifies whether to skip checking if the OIDC token's
|
||||
// issuer claim matches the issuer specified in OidcIssuer. It will be used when
|
||||
// AuthenticationMethod == "oidc". By default, this value is false.
|
||||
OidcSkipIssuerCheck bool `json:"oidc_skip_issuer_check"`
|
||||
OidcSkipIssuerCheck bool `ini:"oidc_skip_issuer_check" json:"oidc_skip_issuer_check"`
|
||||
}
|
||||
|
||||
func getDefaultOidcServerConf() oidcServerConfig {
|
||||
return oidcServerConfig{
|
||||
func getDefaultOidcServerConf() OidcServerConfig {
|
||||
return OidcServerConfig{
|
||||
OidcIssuer: "",
|
||||
OidcAudience: "",
|
||||
OidcSkipExpiryCheck: false,
|
||||
@@ -109,44 +81,13 @@ func getDefaultOidcServerConf() oidcServerConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalOidcServerConfFromIni(conf ini.File) oidcServerConfig {
|
||||
var (
|
||||
tmpStr string
|
||||
ok bool
|
||||
)
|
||||
|
||||
cfg := getDefaultOidcServerConf()
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_issuer"); ok {
|
||||
cfg.OidcIssuer = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_audience"); ok {
|
||||
cfg.OidcAudience = tmpStr
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_skip_expiry_check"); ok && tmpStr == "true" {
|
||||
cfg.OidcSkipExpiryCheck = true
|
||||
} else {
|
||||
cfg.OidcSkipExpiryCheck = false
|
||||
}
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "oidc_skip_issuer_check"); ok && tmpStr == "true" {
|
||||
cfg.OidcSkipIssuerCheck = true
|
||||
} else {
|
||||
cfg.OidcSkipIssuerCheck = false
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type OidcAuthProvider struct {
|
||||
baseConfig
|
||||
BaseConfig
|
||||
|
||||
tokenGenerator *clientcredentials.Config
|
||||
}
|
||||
|
||||
func NewOidcAuthSetter(baseCfg baseConfig, cfg oidcClientConfig) *OidcAuthProvider {
|
||||
func NewOidcAuthSetter(baseCfg BaseConfig, cfg OidcClientConfig) *OidcAuthProvider {
|
||||
tokenGenerator := &clientcredentials.Config{
|
||||
ClientID: cfg.OidcClientID,
|
||||
ClientSecret: cfg.OidcClientSecret,
|
||||
@@ -155,7 +96,7 @@ func NewOidcAuthSetter(baseCfg baseConfig, cfg oidcClientConfig) *OidcAuthProvid
|
||||
}
|
||||
|
||||
return &OidcAuthProvider{
|
||||
baseConfig: baseCfg,
|
||||
BaseConfig: baseCfg,
|
||||
tokenGenerator: tokenGenerator,
|
||||
}
|
||||
}
|
||||
@@ -192,13 +133,13 @@ func (auth *OidcAuthProvider) SetNewWorkConn(newWorkConnMsg *msg.NewWorkConn) (e
|
||||
}
|
||||
|
||||
type OidcAuthConsumer struct {
|
||||
baseConfig
|
||||
BaseConfig
|
||||
|
||||
verifier *oidc.IDTokenVerifier
|
||||
subjectFromLogin string
|
||||
}
|
||||
|
||||
func NewOidcAuthVerifier(baseCfg baseConfig, cfg oidcServerConfig) *OidcAuthConsumer {
|
||||
func NewOidcAuthVerifier(baseCfg BaseConfig, cfg OidcServerConfig) *OidcAuthConsumer {
|
||||
provider, err := oidc.NewProvider(context.Background(), cfg.OidcIssuer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -210,7 +151,7 @@ func NewOidcAuthVerifier(baseCfg baseConfig, cfg oidcServerConfig) *OidcAuthCons
|
||||
SkipIssuerCheck: cfg.OidcSkipIssuerCheck,
|
||||
}
|
||||
return &OidcAuthConsumer{
|
||||
baseConfig: baseCfg,
|
||||
BaseConfig: baseCfg,
|
||||
verifier: provider.Verifier(&verifierConf),
|
||||
}
|
||||
}
|
||||
|
@@ -20,47 +20,30 @@ import (
|
||||
|
||||
"github.com/fatedier/frp/pkg/msg"
|
||||
"github.com/fatedier/frp/pkg/util/util"
|
||||
|
||||
"github.com/vaughan0/go-ini"
|
||||
)
|
||||
|
||||
type tokenConfig struct {
|
||||
type TokenConfig struct {
|
||||
// Token specifies the authorization token used to create keys to be sent
|
||||
// to the server. The server must have a matching token for authorization
|
||||
// to succeed. By default, this value is "".
|
||||
Token string `json:"token"`
|
||||
Token string `ini:"token" json:"token"`
|
||||
}
|
||||
|
||||
func getDefaultTokenConf() tokenConfig {
|
||||
return tokenConfig{
|
||||
func getDefaultTokenConf() TokenConfig {
|
||||
return TokenConfig{
|
||||
Token: "",
|
||||
}
|
||||
}
|
||||
|
||||
func unmarshalTokenConfFromIni(conf ini.File) tokenConfig {
|
||||
var (
|
||||
tmpStr string
|
||||
ok bool
|
||||
)
|
||||
|
||||
cfg := getDefaultTokenConf()
|
||||
|
||||
if tmpStr, ok = conf.Get("common", "token"); ok {
|
||||
cfg.Token = tmpStr
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type TokenAuthSetterVerifier struct {
|
||||
baseConfig
|
||||
BaseConfig
|
||||
|
||||
token string
|
||||
}
|
||||
|
||||
func NewTokenAuth(baseCfg baseConfig, cfg tokenConfig) *TokenAuthSetterVerifier {
|
||||
func NewTokenAuth(baseCfg BaseConfig, cfg TokenConfig) *TokenAuthSetterVerifier {
|
||||
return &TokenAuthSetterVerifier{
|
||||
baseConfig: baseCfg,
|
||||
BaseConfig: baseCfg,
|
||||
token: cfg.Token,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user