diff --git a/backend/factory/config.go b/backend/factory/config.go
index 6bdd2f27a1b5c7b6417439a46566d5eb5c0ed906..fc98705e3c3a1dc92d83ed2f98446fd5b3434db9 100644
--- a/backend/factory/config.go
+++ b/backend/factory/config.go
@@ -43,6 +43,7 @@ type Configuration struct {
 	WebServer     *WebServer     `yaml:"webServer,omitempty" valid:"optional"`
 	Mongodb       *Mongodb       `yaml:"mongodb" valid:"required"`
 	NrfUri        string         `yaml:"nrfUri" valid:"required"`
+	NrfCertPem    string         `yaml:"nrfCertPem,omitempty" valid:"optional"`
 	BillingServer *BillingServer `yaml:"billingServer,omitempty" valid:"required"`
 }
 
diff --git a/backend/logger/logger.go b/backend/logger/logger.go
index c811f2865b11c0110677134eebaa794c2f2f63c7..fcc57cb89c7d68b6590a469f2aa3a72a65135df9 100644
--- a/backend/logger/logger.go
+++ b/backend/logger/logger.go
@@ -19,6 +19,7 @@ var (
 	GinLog       *logrus.Entry
 	BillingLog   *logrus.Entry
 	FtpServerLog golog.Logger
+	ConsumerLog  *logrus.Entry
 )
 
 func init() {
@@ -36,4 +37,5 @@ func init() {
 	GinLog = NfLog.WithField(logger_util.FieldCategory, "GIN")
 	BillingLog = NfLog.WithField(logger_util.FieldCategory, "BillingLog")
 	FtpServerLog = adapter.NewWrap(BillingLog.Logger).With("component", "Billing", "category", "FTPServer")
+	ConsumerLog = NfLog.WithField(logger_util.FieldCategory, "Consumer")
 }
diff --git a/backend/webui_context/context.go b/backend/webui_context/context.go
index 174a121df79a59a6457fbee81c48aff19f0d14a8..4b5fa3d5e2b953b2240dc9a72f51514580aae4b9 100644
--- a/backend/webui_context/context.go
+++ b/backend/webui_context/context.go
@@ -3,17 +3,26 @@ package webui_context
 import (
 	"fmt"
 
+	"github.com/free5gc/openapi/Nnrf_NFManagement"
 	"github.com/free5gc/openapi/models"
 	"github.com/free5gc/webconsole/backend/billing"
+	"github.com/free5gc/webconsole/backend/factory"
 	"github.com/free5gc/webconsole/backend/logger"
+	"github.com/google/uuid"
 )
 
 var webuiContext WEBUIContext
 
 type WEBUIContext struct {
+	NfInstanceID   string
 	NFProfiles     []models.NfProfile
 	NFOamInstances []NfOamInstance
 	BillingServer  *billing.BillingDomain
+
+	NrfUri             string
+	NrfCertPem         string
+	NFManagementClient *Nnrf_NFManagement.APIClient
+	OAuth2Required     bool
 }
 
 type NfOamInstance struct {
@@ -22,14 +31,22 @@ type NfOamInstance struct {
 	Uri    string
 }
 
-var NrfUri string
+func Init() {
+	webuiContext.NfInstanceID = uuid.New().String()
+	webuiContext.NrfUri = factory.WebuiConfig.Configuration.NrfUri
+	webuiContext.NrfCertPem = factory.WebuiConfig.Configuration.NrfCertPem
+
+	ManagementConfig := Nnrf_NFManagement.NewConfiguration()
+	ManagementConfig.SetBasePath(GetSelf().NrfUri)
+	webuiContext.NFManagementClient = Nnrf_NFManagement.NewAPIClient(ManagementConfig)
+}
 
 func NrfAmfUri() string {
-	return NrfUri + "/nnrf-disc/v1/nf-instances?target-nf-type=AMF&requester-nf-type=AMF"
+	return GetSelf().NrfUri + "/nnrf-disc/v1/nf-instances?target-nf-type=AMF&requester-nf-type=AMF"
 }
 
 func NrfSmfUri() string {
-	return NrfUri + "/nnrf-disc/v1/nf-instances?target-nf-type=SMF&requester-nf-type=AMF"
+	return GetSelf().NrfUri + "/nnrf-disc/v1/nf-instances?target-nf-type=SMF&requester-nf-type=AMF"
 }
 
 func (context *WEBUIContext) UpdateNfProfiles() {
diff --git a/backend/webui_context/nrf.go b/backend/webui_context/nrf_discovery.go
similarity index 100%
rename from backend/webui_context/nrf.go
rename to backend/webui_context/nrf_discovery.go
diff --git a/backend/webui_context/nrf_management.go b/backend/webui_context/nrf_management.go
new file mode 100644
index 0000000000000000000000000000000000000000..5df1f964bc5db00f6e72261344d9b25cd74c413a
--- /dev/null
+++ b/backend/webui_context/nrf_management.go
@@ -0,0 +1,117 @@
+package webui_context
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/free5gc/openapi"
+	"github.com/free5gc/openapi/models"
+	"github.com/free5gc/webconsole/backend/logger"
+)
+
+func SendNFRegistration() error {
+	profile := models.NfProfile{
+		NfInstanceId: GetSelf().NfInstanceID,
+		NfType:       models.NfType_AF,
+		NfStatus:     models.NfStatus_REGISTERED,
+	}
+
+	var nf models.NfProfile
+	var res *http.Response
+	var err error
+
+	for {
+		nf, res, err = GetSelf().
+			NFManagementClient.
+			NFInstanceIDDocumentApi.
+			RegisterNFInstance(context.TODO(), GetSelf().NfInstanceID, profile)
+		if err != nil || res == nil {
+			logger.ConsumerLog.Infof("Webconsole-AF register to NRF Error[%s]", err.Error())
+			time.Sleep(2 * time.Second)
+			continue
+		}
+		defer func() {
+			if resCloseErr := res.Body.Close(); resCloseErr != nil {
+				logger.ConsumerLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr)
+			}
+		}()
+
+		status := res.StatusCode
+		if status == http.StatusOK {
+			// NFUpdate
+			break
+		} else if status == http.StatusCreated {
+			// NFRegister
+			resourceUri := res.Header.Get("Location")
+			GetSelf().NfInstanceID = 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)
+				}
+			}
+			GetSelf().OAuth2Required = oauth2
+			if oauth2 && GetSelf().NrfCertPem == "" {
+				logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.")
+			}
+			break
+		} else {
+			logger.ConsumerLog.Infof("handler returned wrong status code %d", status)
+		}
+	}
+
+	logger.InitLog.Infof("Webconsole-AF Registration to NRF success")
+	return nil
+}
+
+func RetrySendNFRegistration(MaxRetry int) error {
+	retryCount := 0
+	for retryCount < MaxRetry {
+		err := SendNFRegistration()
+		if err == nil {
+			return nil
+		}
+		logger.ConsumerLog.Warnf("Send NFRegistration Failed by %v", err)
+		retryCount++
+	}
+	logger.ConsumerLog.Errorln("[AF] Retry NF Registration has meet maximum")
+	return fmt.Errorf("[AF] Retry NF Registration has meet maximum")
+}
+
+func SendDeregisterNFInstance() (*models.ProblemDetails, error) {
+	logger.ConsumerLog.Infof("Send Deregister NFInstance")
+
+	// ctx, pd, err := GetSelf().GetTokenCtx(models.ServiceName_NNRF_NFM, models.NfType_NRF)
+	// if err != nil {
+	// 	return pd, err
+	// }
+
+	afSelf := GetSelf()
+
+	res, err := afSelf.
+		NFManagementClient.
+		NFInstanceIDDocumentApi.
+		DeregisterNFInstance(context.Background(), afSelf.NfInstanceID)
+	if err == nil {
+		return nil, err
+	} else if res != nil {
+		defer func() {
+			if resCloseErr := res.Body.Close(); resCloseErr != nil {
+				logger.ConsumerLog.Errorf("DeregisterNFInstance response body cannot close: %+v", resCloseErr)
+			}
+		}()
+		if res.Status != err.Error() {
+			return nil, err
+		}
+		problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
+		return &problem, err
+	} else {
+		return nil, openapi.ReportError("server no response")
+	}
+}
diff --git a/backend/webui_service/webui_init.go b/backend/webui_service/webui_init.go
index 71f53f2e9de8a6864f6a69b76a70ae5b0c09097a..01a58bf35d2002b0b8d34ad8034c6e26452d5576 100644
--- a/backend/webui_service/webui_init.go
+++ b/backend/webui_service/webui_init.go
@@ -3,7 +3,10 @@ package webui_service
 import (
 	"io/ioutil"
 	"os"
+	"os/signal"
+	"runtime/debug"
 	"sync"
+	"syscall"
 
 	"github.com/gin-contrib/cors"
 	"github.com/sirupsen/logrus"
@@ -27,6 +30,7 @@ func NewApp(cfg *factory.Config) (*WebuiApp, error) {
 	webui.SetLogLevel(cfg.GetLogLevel())
 	webui.SetReportCaller(cfg.GetLogReportCaller())
 
+	webui_context.Init()
 	webui.webuiCtx = webui_context.GetSelf()
 	return webui, nil
 }
@@ -80,11 +84,32 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 		return
 	}
 
-	nrfUri := factory.WebuiConfig.Configuration.NrfUri
-	webui_context.NrfUri = nrfUri
-
 	logger.InitLog.Infoln("Server started")
 
+	signalChannel := make(chan os.Signal, 1)
+	signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM)
+	go func() {
+		defer func() {
+			if p := recover(); p != nil {
+				// Print stack for panic to log. Fatalf() will let program exit.
+				logger.InitLog.Fatalf("panic: %v\n%s", p, string(debug.Stack()))
+			}
+		}()
+
+		<-signalChannel
+		a.Terminate()
+		os.Exit(0)
+	}()
+
+	err := webui_context.SendNFRegistration()
+	if err != nil {
+		retry_err := webui_context.RetrySendNFRegistration(10)
+		if retry_err != nil {
+			logger.InitLog.Errorln(retry_err)
+			return
+		}
+	}
+
 	router := WebUI.NewRouter()
 	WebUI.SetAdmin()
 	if err := WebUI.InitJwtKey(); err != nil {
@@ -125,3 +150,17 @@ func (a *WebuiApp) Start(tlsKeyLogPath string) {
 
 	wg.Wait()
 }
+
+func (a *WebuiApp) Terminate() {
+	logger.InitLog.Infoln("Terminating WebUI-AF...")
+
+	// Deregister with NRF
+	problemDetails, err := webui_context.SendDeregisterNFInstance()
+	if problemDetails != nil {
+		logger.InitLog.Errorf("Deregister NF instance Failed Problem[%+v]", problemDetails)
+	} else if err != nil {
+		logger.InitLog.Errorf("Deregister NF instance Error[%+v]", err)
+	} else {
+		logger.InitLog.Infof("Deregister from NRF successfully")
+	}
+}
diff --git a/config/webuicfg.yaml b/config/webuicfg.yaml
index 4496ea00d1ac1b586973baba5f248aea6744fee9..e35022f692c0b01f6a97bbf761c3f4e4a580f536 100644
--- a/config/webuicfg.yaml
+++ b/config/webuicfg.yaml
@@ -7,6 +7,7 @@ configuration:
     name: free5gc # name of the mongodb
     url: mongodb://localhost:27017 # a valid URL of the mongodb
   nrfUri: http://127.0.0.10:8000 # a valid URI of NRF
+  nrfCertPem: cert/nrf.pem
   webServer:
     scheme: http
     ipv4Address: 0.0.0.0