mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-05 03:40:01 -06:00
add public share auth middleware
This commit is contained in:
6
changelog/unreleased/public-share-auth-middleware.md
Normal file
6
changelog/unreleased/public-share-auth-middleware.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Enhancement: Add a middleware to authenticate public share requests
|
||||
|
||||
Added a new middleware to authenticate public share requests. This makes it possible to use APIs which require an authenticated context with public shares.
|
||||
|
||||
https://github.com/owncloud/ocis/pull/2536
|
||||
https://github.com/owncloud/ocis/issues/2479
|
||||
@@ -147,7 +147,7 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alice.Chain {
|
||||
func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config) alice.Chain {
|
||||
rolesClient := settings.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient)
|
||||
revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address)
|
||||
var userProvider backend.UserBackend
|
||||
@@ -158,7 +158,7 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
||||
"expires": int64(24 * 60 * 60),
|
||||
})
|
||||
if err != nil {
|
||||
l.Error().Err(err).
|
||||
logger.Error().Err(err).
|
||||
Msg("Failed to create token manager")
|
||||
}
|
||||
userProvider = backend.NewAccountsServiceUserBackend(
|
||||
@@ -166,17 +166,17 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
||||
rolesClient,
|
||||
cfg.OIDC.Issuer,
|
||||
tokenManager,
|
||||
l,
|
||||
logger,
|
||||
)
|
||||
case "cs3":
|
||||
userProvider = backend.NewCS3UserBackend(rolesClient, revaClient, cfg.MachineAuthAPIKey, l)
|
||||
userProvider = backend.NewCS3UserBackend(rolesClient, revaClient, cfg.MachineAuthAPIKey, logger)
|
||||
default:
|
||||
l.Fatal().Msgf("Invalid accounts backend type '%s'", cfg.AccountBackend)
|
||||
logger.Fatal().Msgf("Invalid accounts backend type '%s'", cfg.AccountBackend)
|
||||
}
|
||||
|
||||
storeClient := storepb.NewStoreService("com.owncloud.api.store", grpc.DefaultClient)
|
||||
if err != nil {
|
||||
l.Error().Err(err).
|
||||
logger.Error().Err(err).
|
||||
Str("gateway", cfg.Reva.Address).
|
||||
Msg("Failed to create reva gateway service client")
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
||||
pkgmiddleware.TraceContext,
|
||||
chimiddleware.RealIP,
|
||||
chimiddleware.RequestID,
|
||||
middleware.AccessLog(l),
|
||||
middleware.AccessLog(logger),
|
||||
middleware.HTTPSRedirect,
|
||||
|
||||
// now that we established the basics, on with authentication middleware
|
||||
@@ -216,20 +216,24 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
||||
middleware.TokenCacheTTL(time.Second*time.Duration(cfg.OIDC.UserinfoCache.TTL)),
|
||||
|
||||
// basic Options
|
||||
middleware.Logger(l),
|
||||
middleware.Logger(logger),
|
||||
middleware.EnableBasicAuth(cfg.EnableBasicAuth),
|
||||
middleware.UserProvider(userProvider),
|
||||
middleware.OIDCIss(cfg.OIDC.Issuer),
|
||||
middleware.CredentialsByUserAgent(cfg.Reva.Middleware.Auth.CredentialsByUserAgent),
|
||||
),
|
||||
middleware.PublicShareAuth(
|
||||
middleware.Logger(logger),
|
||||
middleware.RevaGatewayClient(revaClient),
|
||||
),
|
||||
middleware.SignedURLAuth(
|
||||
middleware.Logger(l),
|
||||
middleware.Logger(logger),
|
||||
middleware.PreSignedURLConfig(cfg.PreSignedURL),
|
||||
middleware.UserProvider(userProvider),
|
||||
middleware.Store(storeClient),
|
||||
),
|
||||
middleware.AccountResolver(
|
||||
middleware.Logger(l),
|
||||
middleware.Logger(logger),
|
||||
middleware.UserProvider(userProvider),
|
||||
middleware.TokenManagerConfig(cfg.TokenManager),
|
||||
middleware.UserOIDCClaim(cfg.UserOIDCClaim),
|
||||
@@ -238,14 +242,14 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
|
||||
),
|
||||
|
||||
middleware.SelectorCookie(
|
||||
middleware.Logger(l),
|
||||
middleware.Logger(logger),
|
||||
middleware.UserProvider(userProvider),
|
||||
middleware.PolicySelectorConfig(*cfg.PolicySelector),
|
||||
),
|
||||
|
||||
// finally, trigger home creation when a user logs in
|
||||
middleware.CreateHome(
|
||||
middleware.Logger(l),
|
||||
middleware.Logger(logger),
|
||||
middleware.TokenManagerConfig(cfg.TokenManager),
|
||||
middleware.RevaGatewayClient(revaClient),
|
||||
),
|
||||
|
||||
58
proxy/pkg/middleware/public_share_auth.go
Normal file
58
proxy/pkg/middleware/public_share_auth.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
headerRevaAccessToken = "x-access-token"
|
||||
headerShareToken = "public-token"
|
||||
appProviderPathPrefix = "/app/open"
|
||||
basicAuthPasswordPrefix = "basic|"
|
||||
authenticationType = "publicshares"
|
||||
)
|
||||
|
||||
// PublicShareAuth ...
|
||||
func PublicShareAuth(opts ...Option) func(next http.Handler) http.Handler {
|
||||
options := newOptions(opts...)
|
||||
logger := options.Logger
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Currently we only want to authenticate app open request coming from public shares.
|
||||
shareToken := r.Header.Get(headerShareToken)
|
||||
if shareToken == "" || !strings.HasPrefix(appProviderPathPrefix, r.URL.Path) {
|
||||
// Don't authenticate
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// We can ignore the username since it is always set to "public" in public shares.
|
||||
_, password, ok := r.BasicAuth()
|
||||
|
||||
sharePassword := basicAuthPasswordPrefix
|
||||
if ok {
|
||||
sharePassword += password
|
||||
}
|
||||
|
||||
authResp, err := options.RevaGatewayClient.Authenticate(r.Context(), &gateway.AuthenticateRequest{
|
||||
Type: authenticationType,
|
||||
ClientId: shareToken,
|
||||
ClientSecret: sharePassword,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
logger.Debug().Err(err).Str("public_share_token", shareToken).Msg("could not authenticate public share")
|
||||
// try another middleware
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
r.Header.Add(headerRevaAccessToken, authResp.Token)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user