Skip to content

Commit

Permalink
Feature: Add NRF Consumer support OAuth2 (#112)
Browse files Browse the repository at this point in the history
* Feature: Add NRF Consumer support OAuth2

* Fix lint error

* fix variable name

* Fix: minor changes

* Fix: prevent assertion and modify config setting

* Fix: move GetTokenCtx() and fix minor logic

* Fix: Remove unused condition

---------

Co-authored-by: CTFang@WireLab <[email protected]>
  • Loading branch information
andy89923 and andy89923 authored Dec 19, 2023
1 parent bd71c8a commit 5e0fac4
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 15 deletions.
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

0 comments on commit 5e0fac4

Please sign in to comment.