-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/k8s token authentication #64
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
base: main
Are you sure you want to change the base?
Changes from all commits
23f2560
bce86e4
bcbfdf0
f4688ef
3a96bfc
0140521
1ac1244
40eb416
8fab3be
310865c
dce2d18
695104e
fb12881
43cb92c
0cb488c
457d0af
4559cd0
72c4ff3
f116fd9
4500a41
770195b
4c51c9f
83d3492
f08cfb5
f0f50db
9705ea7
f6d519e
ebb226b
7063834
f87b0f6
a3d5257
b22b36f
b8bda8a
6ece949
42a036a
8f4a008
2f595a6
7850c08
fd80b6a
712a9fb
595e0b1
9452140
2801bc6
b7987a7
169f664
61b368b
877b836
6f92c54
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| issuer: http://oidc-server:5556/dex | ||
|
|
||
| storage: | ||
| type: sqlite3 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need sqlite3 for tests? |
||
|
|
||
| web: | ||
| http: 0.0.0.0:5556 | ||
|
|
||
| telemetry: | ||
| http: 0.0.0.0:5558 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this port used? |
||
|
|
||
| grpc: | ||
| addr: 0.0.0.0:5557 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this port used? |
||
|
|
||
| connectors: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do we mock? |
||
| - type: mockCallback | ||
| id: mock | ||
| name: Example | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -124,7 +124,7 @@ func (a *AccountController) SaveManagerAccount(fiberCtx *fiber.Ctx) error { | |
| } | ||
|
|
||
| log.InfoC(ctx, "Received request on create one more manage account") | ||
| if _, err := a.service.IsAccessGranted(ctx, username, password, model.ManagerAccountNamespace, []model.RoleName{model.ManagerRole}); err != nil { | ||
| if _, err := a.service.IsAccessGrantedWithBasic(ctx, username, password, model.ManagerAccountNamespace, []model.RoleName{model.ManagerRole}); err != nil { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so we have no option to create manager accounts with token? how can we deprecate the basic auth approach then?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what about client account for deployer v3?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is not decided yet. it will be decided when maas becomes an operator. see stage 3 here. https://bass.netcracker.com/display/CPSEC/M2M+MaaS+Design |
||
| return utils.LogError(log, ctx, "password verification does not passed: %w", err) | ||
| } | ||
| if managerAccount, err := a.service.CreateNewManager(ctx, &accountRequest); err != nil { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,11 @@ import ( | |
| "encoding/json" | ||
| "errors" | ||
| "fmt" | ||
| "net/http" | ||
| "regexp" | ||
| "strconv" | ||
| "strings" | ||
|
|
||
| "github.com/go-playground/validator/v10" | ||
| "github.com/gofiber/fiber/v2" | ||
| "github.com/google/uuid" | ||
|
|
@@ -17,10 +22,6 @@ import ( | |
| v "github.com/netcracker/qubership-maas/validator" | ||
| "golang.org/x/exp/slices" | ||
| "gopkg.in/yaml.v3" | ||
| "net/http" | ||
| "regexp" | ||
| "strconv" | ||
| "strings" | ||
| ) | ||
|
|
||
| const ( | ||
|
|
@@ -59,28 +60,57 @@ func init() { | |
|
|
||
| type RequestBodyHandler func(ctx context.Context) (interface{}, error) | ||
|
|
||
| func SecurityMiddleware(roles []model.RoleName, authorize func(context.Context, string, utils.SecretString, string, []model.RoleName) (*model.Account, error)) fiber.Handler { | ||
| type authorizeWithBasicFunc func(context.Context, string, utils.SecretString, string, []model.RoleName) (*model.Account, error) | ||
| type authorizeWithTokenFunc func(context.Context, string, string, []model.RoleName) (*model.Account, error) | ||
|
|
||
| func SecurityMiddleware(roles []model.RoleName, authorizeWithBasic authorizeWithBasicFunc, authorizeWithToken authorizeWithTokenFunc) fiber.Handler { | ||
| return func(ctx *fiber.Ctx) error { | ||
| userCtx := ctx.UserContext() | ||
| username, password, err := utils.GetBasicAuth(ctx) | ||
| if err != nil { | ||
| namespace := string(ctx.Request().Header.Peek(HeaderXNamespace)) | ||
| authHeader := string(ctx.Request().Header.Peek(fiber.HeaderAuthorization)) | ||
|
|
||
| var ( | ||
| account *model.Account | ||
| // in kubernetes m2m auth composite isolation is always enabled | ||
| compositeIsolationDisabled = false | ||
| ) | ||
|
|
||
| authScheme, creds, ok := utils.ParseAuthHeader(authHeader) | ||
| if !ok { | ||
| if slices.Contains(roles, model.AnonymousRole) { | ||
| log.WarnC(userCtx, "Anonymous access will be dropped in future releases for: %s", ctx.OriginalURL()) | ||
| return ctx.Next() | ||
| } | ||
| return utils.LogError(log, userCtx, "security middleware error: %w", err) | ||
| return utils.LogError(log, userCtx, "request authorization failure: invalid auth header: %w", msg.AuthError) | ||
| } | ||
|
|
||
| namespace := string(ctx.Request().Header.Peek(HeaderXNamespace)) | ||
| switch strings.ToLower(authScheme) { | ||
| case "basic": | ||
| username, password, err := utils.GetBasicAuth(ctx) | ||
| if err != nil { | ||
| return utils.LogError(log, userCtx, "security middleware error: %w", err) | ||
| } | ||
|
|
||
| acc, err := authorize(ctx.UserContext(), username, password, namespace, roles) | ||
| if err != nil { | ||
| return utils.LogError(log, userCtx, "request authorization failure: %w", err) | ||
| account, err = authorizeWithBasic(userCtx, username, password, namespace, roles) | ||
| if err != nil { | ||
| return utils.LogError(log, userCtx, "request authorization failure: %w", err) | ||
| } | ||
| compositeIsolationDisabled = strings.ToLower(string(ctx.Request().Header.Peek(HeaderXCompositeIsolationDisabled))) == "disabled" | ||
| case "bearer": | ||
| serviceAccount, err := authorizeWithToken(userCtx, creds, namespace, roles) | ||
| if err != nil { | ||
| return utils.LogError(log, userCtx, "request authorization failure: %w", err) | ||
| } | ||
| account = serviceAccount | ||
| default: | ||
| if slices.Contains(roles, model.AnonymousRole) { | ||
| log.WarnC(userCtx, "Anonymous access will be dropped in future releases for: %s", ctx.OriginalURL()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. code duplication. just check if the role == AnonymousRole in the beginning and skip other steps |
||
| return ctx.Next() | ||
| } | ||
| return utils.LogError(log, userCtx, "security middleware error: %w", msg.AuthError) | ||
| } | ||
|
|
||
| compositeIsolationDisabled := strings.ToLower(string(ctx.Request().Header.Peek(HeaderXCompositeIsolationDisabled))) == "disabled" | ||
|
|
||
| secCtx := model.NewSecurityContext(acc, compositeIsolationDisabled) | ||
| secCtx := model.NewSecurityContext(account, compositeIsolationDisabled) | ||
| ctx.SetUserContext(model.WithSecurityContext(userCtx, secCtx)) | ||
| return ctx.Next() | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where are the actual tests that use new auth ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is added because when application starts it looks for token and makes OIDC discovery. and this is added to prevent app from crashing at start in tests