mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-31 01:10:20 -06:00
appauth: Add token and user (with roles) to context
When successfully authenticating a user via apptoken, resolve the user's roles and add the user and the token returned by the auth service to the request context. Rely on the account_resolve middleware to add the reva token to the outgoing request as the other auth middlewares do.
This commit is contained in:
@@ -294,6 +294,7 @@ func loadMiddlewares(logger log.Logger, cfg *config.Config,
|
||||
authenticators = append(authenticators, middleware.AppAuthAuthenticator{
|
||||
Logger: logger,
|
||||
RevaGatewaySelector: gatewaySelector,
|
||||
UserRoleAssigner: roleAssigner,
|
||||
})
|
||||
}
|
||||
authenticators = append(authenticators, middleware.NewOIDCAuthenticator(
|
||||
|
||||
@@ -99,8 +99,7 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := req.Context()
|
||||
claims := oidc.FromContext(ctx)
|
||||
user, ok := revactx.ContextGetUser(ctx)
|
||||
token := ""
|
||||
// TODO what if an X-Access-Token is set? happens eg for download requests to the /data endpoint in the reva frontend
|
||||
token, hasToken := revactx.ContextGetToken(ctx)
|
||||
|
||||
if claims == nil && !ok {
|
||||
m.next.ServeHTTP(w, req)
|
||||
@@ -192,10 +191,11 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
m.logger.Debug().Interface("claims", claims).Interface("user", user).Msg("associated claims with user")
|
||||
} else if user != nil {
|
||||
} else if user != nil && !hasToken {
|
||||
// If we already have a token (e.g. the app auth middleware adds the token to the context) there is no need
|
||||
// to get yet another one here.
|
||||
var err error
|
||||
_, token, err = m.userProvider.GetUserByClaims(req.Context(), "username", user.Username)
|
||||
|
||||
if errors.Is(err, backend.ErrAccountDisabled) {
|
||||
m.logger.Debug().Interface("user", user).Msg("Disabled")
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
"github.com/opencloud-eu/opencloud/services/proxy/pkg/userroles"
|
||||
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
|
||||
)
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
type AppAuthAuthenticator struct {
|
||||
Logger log.Logger
|
||||
RevaGatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||
UserRoleAssigner userroles.UserRoleAssigner
|
||||
}
|
||||
|
||||
// Authenticate implements the authenticator interface to authenticate requests via app auth.
|
||||
@@ -43,11 +45,20 @@ func (m AppAuthAuthenticator) Authenticate(r *http.Request) (*http.Request, bool
|
||||
return nil, false
|
||||
}
|
||||
if authenticateResponse.GetStatus().GetCode() != cs3rpc.Code_CODE_OK {
|
||||
// TODO: log???
|
||||
m.Logger.Debug().Str("msg", authenticateResponse.GetStatus().GetMessage()).Str("clientid", username).Msg("app auth failed")
|
||||
return nil, false
|
||||
}
|
||||
|
||||
r.Header.Set(revactx.TokenHeader, authenticateResponse.GetToken())
|
||||
user := authenticateResponse.GetUser()
|
||||
if user, err = m.UserRoleAssigner.ApplyUserRole(r.Context(), user); err != nil {
|
||||
m.Logger.Error().Err(err).Str("clientid", username).Msg("app auth: failed to load user roles")
|
||||
return nil, false
|
||||
}
|
||||
|
||||
ctx := revactx.ContextSetUser(r.Context(), user)
|
||||
ctx = revactx.ContextSetToken(ctx, authenticateResponse.GetToken())
|
||||
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
return r, true
|
||||
}
|
||||
|
||||
@@ -5,19 +5,24 @@ import (
|
||||
"net/http/httptest"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/opencloud-eu/opencloud/pkg/log"
|
||||
userRoleMocks "github.com/opencloud-eu/opencloud/services/proxy/pkg/userroles/mocks"
|
||||
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var _ = Describe("Authenticating requests", Label("AppAuthAuthenticator"), func() {
|
||||
var authenticator Authenticator
|
||||
BeforeEach(func() {
|
||||
pool.RemoveSelector("GatewaySelector" + "eu.opencloud.api.gateway")
|
||||
ra := &userRoleMocks.UserRoleAssigner{}
|
||||
ra.On("ApplyUserRole", mock.Anything, mock.Anything, mock.Anything).Return(&userv1beta1.User{}, nil)
|
||||
authenticator = AppAuthAuthenticator{
|
||||
Logger: log.NewLogger(),
|
||||
RevaGatewaySelector: pool.GetSelector[gateway.GatewayAPIClient](
|
||||
@@ -39,6 +44,7 @@ var _ = Describe("Authenticating requests", Label("AppAuthAuthenticator"), func(
|
||||
}
|
||||
},
|
||||
),
|
||||
UserRoleAssigner: ra,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -51,7 +57,12 @@ var _ = Describe("Authenticating requests", Label("AppAuthAuthenticator"), func(
|
||||
|
||||
Expect(valid).To(Equal(true))
|
||||
Expect(req2).ToNot(BeNil())
|
||||
Expect(req2.Header.Get("x-access-token")).To(Equal("reva-token"))
|
||||
user, ok := revactx.ContextGetUser(req2.Context())
|
||||
Expect(ok).To(BeTrue())
|
||||
Expect(user).ToNot(BeNil())
|
||||
token, ok := revactx.ContextGetToken(req2.Context())
|
||||
Expect(ok).To(BeTrue())
|
||||
Expect(token).To(Equal("reva-token"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user