Skip to content

Commit

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

* Add nrfCerPem config

* modify log level

* fix variable name

* Fix: add minor changes

* Fix: prevent assertion and modify config setting

* Fix: move GetTokenCtx() and remove unnecessary condition

* Fix: fix linter error

---------

Co-authored-by: CTFang@WireLab <[email protected]>
  • Loading branch information
andy89923 and andy89923 authored Dec 19, 2023
1 parent 0217fbc commit 64e4ed5
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 9 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.17
require (
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/evanphx/json-patch v0.5.2
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94
github.com/gin-gonic/gin v1.9.1
github.com/google/uuid v1.3.0
Expand Down
8 changes: 5 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
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.20231112094355-a96c3450377e h1:mXnoioq+fxpChliDl5Uy+m6+Hm7iWrJPZo9mi6BijHE=
github.com/free5gc/openapi v1.0.7-0.20231112094355-a96c3450377e/go.mod h1:qv9KqEucoZSeENPRFGxfTe+33ZWYyiYFx1Rj+H0DoWA=
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/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94/go.mod h1:aMszJZbCkcg5xaGgzya+55jz+OPMsJqPLq5Z3fWDFPE=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
Expand Down Expand Up @@ -305,7 +307,6 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
Expand Down Expand Up @@ -522,6 +523,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
16 changes: 15 additions & 1 deletion internal/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package context

import (
"context"
"fmt"
"os"
"strconv"
Expand All @@ -18,6 +19,7 @@ import (
"github.com/free5gc/nssf/internal/logger"
"github.com/free5gc/nssf/pkg/factory"
"github.com/free5gc/openapi/models"
"github.com/free5gc/openapi/oauth"
)

var nssfContext = NSSFContext{}
Expand Down Expand Up @@ -51,7 +53,9 @@ type NSSFContext struct {
SBIPort int
NfService map[models.ServiceName]models.NfService
NrfUri string
NrfCertPem string
SupportedPlmnList []models.PlmnId
OAuth2Required bool
}

// Initialize NSSF context with configuration factory
Expand Down Expand Up @@ -83,7 +87,7 @@ func InitNssfContext() {
logger.InitLog.Warn("NRF Uri is empty! Using localhost as NRF IPv4 address.")
nssfContext.NrfUri = fmt.Sprintf("%s://%s:%d", nssfContext.UriScheme, "127.0.0.1", 29510)
}

nssfContext.NrfCertPem = nssfConfig.Configuration.NrfCertPem
nssfContext.SupportedPlmnList = nssfConfig.Configuration.SupportedPlmnList
}

Expand Down Expand Up @@ -125,3 +129,13 @@ func GetIpv4Uri() string {
func GetSelf() *NSSFContext {
return &nssfContext
}

func (c *NSSFContext) GetTokenCtx(scope, targetNF string) (
context.Context, *models.ProblemDetails, error,
) {
if !c.OAuth2Required {
return context.TODO(), nil, nil
}
return oauth.GetTokenCtx(models.NfType_NSSF,
c.NfId, c.NrfUri, scope, targetNF)
}
26 changes: 23 additions & 3 deletions internal/sbi/consumer/nf_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
apiClient := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
var nf models.NfProfile
for {
_, res, err = apiClient.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
nf, res, err = apiClient.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
if err != nil || res == nil {
// TODO : add log
logger.ConsumerLog.Errorf("NSSF register to NRF Error[%s]", err.Error())
Expand All @@ -66,6 +67,19 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
resourceUri := res.Header.Get("Location")
resourceNrfUri = 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)
}
}
nssf_context.GetSelf().OAuth2Required = oauth2
if oauth2 && nssf_context.GetSelf().NrfCertPem == "" {
logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.")
}
break
} else {
fmt.Println("NRF return wrong status code", status)
Expand All @@ -77,16 +91,22 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
func SendDeregisterNFInstance() (*models.ProblemDetails, error) {
logger.ConsumerLog.Infof("Send Deregister NFInstance")

var err error

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

nssfSelf := nssf_context.GetSelf()
// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
configuration.SetBasePath(nssfSelf.NrfUri)
client := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
var err error

res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(context.Background(), nssfSelf.NfId)
res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, nssfSelf.NfId)
if err == nil {
return nil, err
} else if res != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func parseQueryParameter(query url.Values) (plugin.NsselectionQueryParameter, er

// Check if the NF service consumer is authorized
// TODO: Check if the NF service consumer is legal with local configuration, or possibly after querying NRF through
// `nf-id` e.g. Whether the V-NSSF is authorized
// `nf-id` e.g. Whether the V-NSSF is authorized
func checkNfServiceConsumer(nfType models.NfType) error {
if nfType != models.NfType_AMF && nfType != models.NfType_NSSF {
return fmt.Errorf("`nf-type`:'%s' is not authorized to retrieve the slice selection information", string(nfType))
Expand Down
1 change: 1 addition & 0 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type Configuration struct {
Sbi *Sbi `yaml:"sbi"`
ServiceNameList []models.ServiceName `yaml:"serviceNameList"`
NrfUri string `yaml:"nrfUri"`
NrfCertPem string `yaml:"nrfCertPem,omitempty" valid:"optional"`
SupportedPlmnList []models.PlmnId `yaml:"supportedPlmnList,omitempty"`
SupportedNssaiInPlmnList []SupportedNssaiInPlmn `yaml:"supportedNssaiInPlmnList"`
NsiList []NsiConfig `yaml:"nsiList,omitempty"`
Expand Down

0 comments on commit 64e4ed5

Please sign in to comment.