Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add NRF Consumer support OAuth2 #112

Merged
merged 7 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/free5gc/aper v1.0.5-0.20230614030933-c73735898582
github.com/free5gc/nas v1.1.2-0.20230828074825-175b09665828
github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6
github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94
github.com/gin-contrib/cors v1.3.1
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ github.com/free5gc/nas v1.1.2-0.20230828074825-175b09665828/go.mod h1:fjWwpyp7/w
github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f h1:wgXjoknZ7JJoZ72J15g/f2/0DgdCpfcTg189lnhUPuY=
github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f/go.mod h1:lKA1sLTYM3CGEBhZVxkGGJIkai5+Bvy2yHIMhb7Vx/k=
github.com/free5gc/openapi v1.0.6/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6 h1:8P/wOkTAQMgZJe9pUUNSTE5PWeAdlMrsU9kLsI+VAVE=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6/go.mod h1:qv9KqEucoZSeENPRFGxfTe+33ZWYyiYFx1Rj+H0DoWA=
github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9 h1:L02UI8oODfXgH1fGzWWuWF4zyze4IScEFm20q3PKZdE=
github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9/go.mod h1:Nr81VlvMkBHZsCbWPXjosBh+SWLdeEyz8o0OrS110Ic=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY=
Expand Down Expand Up @@ -556,6 +556,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
18 changes: 18 additions & 0 deletions internal/context/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package context

import (
"context"
"fmt"
"math"
"net"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/free5gc/nas/security"
"github.com/free5gc/openapi"
"github.com/free5gc/openapi/models"
"github.com/free5gc/openapi/oauth"
"github.com/free5gc/util/idgenerator"
)

Expand Down Expand Up @@ -66,6 +68,7 @@ type AMFContext struct {
SupportDnnLists []string
AMFStatusSubscriptions sync.Map // map[subscriptionID]models.SubscriptionData
NrfUri string
NrfCertPem string
SecurityAlgorithm SecurityAlgorithm
NetworkName factory.NetworkName
NgapIpList []string // NGAP Server IP
Expand All @@ -83,6 +86,8 @@ type AMFContext struct {
T3570Cfg factory.TimerValue
T3555Cfg factory.TimerValue
Locality string

OAuth2Required bool
}

type AMFContextEventSubscription struct {
Expand Down Expand Up @@ -126,6 +131,7 @@ func InitAmfContext(context *AMFContext) {
context.LadnPool[ladn.Dnn] = ladn
}
context.NrfUri = config.GetNrfUri()
context.NrfCertPem = configuration.NrfCertPem
security := configuration.Security
if security != nil {
context.SecurityAlgorithm.IntegrityOrder = getIntAlgOrder(security.IntegrityOrder)
Expand Down Expand Up @@ -536,9 +542,21 @@ func (context *AMFContext) Reset() {
context.HttpIPv6Address = ""
context.Name = "amf"
context.NrfUri = ""
context.NrfCertPem = ""
context.OAuth2Required = false
}

// Create new AMF context
func GetSelf() *AMFContext {
return &amfContext
}

func (c *AMFContext) GetTokenCtx(scope, targetNF string) (
context.Context, *models.ProblemDetails, error,
) {
if !c.OAuth2Required {
return context.TODO(), nil, nil
}
return oauth.GetTokenCtx(models.NfType_AMF,
c.NfId, c.NrfUri, scope, targetNF)
}
14 changes: 9 additions & 5 deletions internal/sbi/consumer/nf_discovery.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package consumer

import (
"context"
"fmt"
"net/http"

Expand All @@ -14,18 +13,23 @@ import (

func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType,
param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts,
) (models.SearchResult, error) {
) (*models.SearchResult, error) {
// Set client and set url
configuration := Nnrf_NFDiscovery.NewConfiguration()
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, param)
ctx, _, err := amf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF")
if err != nil {
return nil, err
}

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, param)
if res != nil && res.StatusCode == http.StatusTemporaryRedirect {
err = fmt.Errorf("Temporary Redirect For Non NRF Consumer")
}
if res == nil || res.Body == nil {
return result, err
return &result, err
}
defer func() {
if res != nil {
Expand All @@ -34,7 +38,7 @@ func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfT
}
}
}()
return result, err
return &result, err
}

func SearchUdmSdmInstance(ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NfType,
Expand Down
30 changes: 25 additions & 5 deletions internal/sbi/consumer/nf_mangement.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
client := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
var nf models.NfProfile
for {
_, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
if err != nil || res == nil {
// TODO : add log
fmt.Println(fmt.Errorf("AMF register to NRF Error[%s]", err.Error()))
Expand All @@ -104,6 +105,20 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
resourceUri := res.Header.Get("Location")
resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")]
retrieveNfInstanceId = resourceUri[strings.LastIndex(resourceUri, "/")+1:]

oauth2 := false
if nf.CustomInfo != nil {
v, ok := nf.CustomInfo["oauth2"].(bool)
if ok {
oauth2 = v
logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2)
}
}
amf_context.GetSelf().OAuth2Required = oauth2
if oauth2 && amf_context.GetSelf().NrfCertPem == "" {
logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.")
}

break
} else {
fmt.Println(fmt.Errorf("handler returned wrong status code %d", status))
Expand All @@ -116,6 +131,11 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Infof("[AMF] Send Deregister NFInstance")

ctx, pd, err := amf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF")
if err != nil {
return pd, err
}

amfSelf := amf_context.GetSelf()
// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
Expand All @@ -124,22 +144,22 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro

var res *http.Response

res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(context.Background(), amfSelf.NfId)
res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, amfSelf.NfId)
if err == nil {
return
return problemDetails, err
} else if res != nil {
defer func() {
if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil {
err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr)
}
}()
if res.Status != err.Error() {
return
return problemDetails, err
}
problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
} else {
err = openapi.ReportError("server no response")
}
return
return problemDetails, err
}
4 changes: 2 additions & 2 deletions internal/sbi/consumer/subscriber_data_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ func SDMUnsubscribe(ue *amf_context.AmfUe) (problemDetails *models.ProblemDetail
}
}()
if localErr == nil {
return
return problemDetails, err
} else if httpResp != nil {
if httpResp.Status != localErr.Error() {
err = localErr
return
return problemDetails, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down
1 change: 1 addition & 0 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type Configuration struct {
SupportDnnList []string `yaml:"supportDnnList,omitempty" valid:"required"`
SupportLadnList []Ladn `yaml:"supportLadnList,omitempty" valid:"optional"`
NrfUri string `yaml:"nrfUri,omitempty" valid:"required, url"`
NrfCertPem string `yaml:"nrfCertPem,omitempty" valid:"optional"`
Security *Security `yaml:"security,omitempty" valid:"required"`
NetworkName NetworkName `yaml:"networkName,omitempty" valid:"required"`
NgapIE *NgapIE `yaml:"ngapIE,omitempty" valid:"optional"`
Expand Down