diff --git a/docs/en/02-configuration.md b/docs/en/02-configuration.md index 893a0a4..303a021 100644 --- a/docs/en/02-configuration.md +++ b/docs/en/02-configuration.md @@ -121,8 +121,6 @@ HTTP server CORS config. If not set, no CORS settings will be applied. If set to non-empty string, JWT provider is created for API tokens verification. -> API tokens allow access only for [`/seqapi/*`, `/massexport/*`] routes in HTTP API and [`SeqAPIService`, `MassExportService`] service in gRPC API. For other routes/services requiring auth, OIDC check will be performed, so `jwt_secret_key` should be used in pair with `oidc`. - **`oidc`** *`OIDC`* *`optional`* Open ID Connect config. If not set, no OIDC verification will be applied. diff --git a/docs/ru/02-configuration.md b/docs/ru/02-configuration.md index d42faa0..e9dde32 100644 --- a/docs/ru/02-configuration.md +++ b/docs/ru/02-configuration.md @@ -121,8 +121,6 @@ server: Если задана непустая строка, то создается JWT-провайдер для верификации токенов. -> Авторизация по токенам разрешена только для обработчиков [`/seqapi/*`, `/massexport/*`] в HTTP API и сервисам [`SeqAPIService`, `MassExportService`] в gRPC API. Для других обработчиков/сервисов, требующих авторизацию, будет использоваться OIDC, поэтому `jwt_secret_key` следует использовать в паре с `oidc`. - **`oidc`** *`OIDC`* *`optional`* Конфигурация Open ID Connect. Если не задано, то верификации по OIDC не будет. diff --git a/internal/app/mw/auth.go b/internal/app/mw/auth.go index 93d8880..a927e2d 100644 --- a/internal/app/mw/auth.go +++ b/internal/app/mw/auth.go @@ -13,15 +13,6 @@ import ( var errAuthProviderNotInit = errors.New("auth provider was not initialized") -var ( - tokenAuthServices = map[string]struct{}{ - "seqapi": {}, - "massexport": {}, - "SeqAPIService": {}, - "MassExportService": {}, - } -) - const authHeaderBearerKey = "Bearer" func getTokenFromAuthHeader(authHeader string) (string, error) { @@ -64,12 +55,12 @@ func NewAuthProviders( return authPrvds, nil } -func (p *AuthProviders) auth(ctx context.Context, authHeader string, checkAPIToken bool) (string, error) { +func (p *AuthProviders) auth(ctx context.Context, authHeader string) (string, error) { token, err := getTokenFromAuthHeader(authHeader) if err != nil { return "", fmt.Errorf("failed to get token from auth header: %w", err) } - if checkAPIToken && p.JwtProvider != nil { + if p.JwtProvider != nil { // first check if token was issued by the app's JWT provider jwtClaims, err := p.JwtProvider.Verify(token) if err == nil { diff --git a/internal/app/mw/auth_test.go b/internal/app/mw/auth_test.go index 36e9a3c..fc56b91 100644 --- a/internal/app/mw/auth_test.go +++ b/internal/app/mw/auth_test.go @@ -46,9 +46,8 @@ func TestAuthProvidersAuth(t *testing.T) { tCases := []struct { name string - authHeader string - checkAPIToken bool - mockArgs mockArgs + authHeader string + mockArgs mockArgs want string wantErr bool @@ -59,9 +58,8 @@ func TestAuthProvidersAuth(t *testing.T) { wantErr: true, }, { - name: "ok_jwt_only", - authHeader: authHeader, - checkAPIToken: true, + name: "ok_jwt_only", + authHeader: authHeader, mockArgs: mockArgs{ jwt: &jwtMockArgs{ token: token, @@ -71,9 +69,8 @@ func TestAuthProvidersAuth(t *testing.T) { want: formatJWTServiceName(userName), }, { - name: "err_jwt_only", - authHeader: authHeader, - checkAPIToken: true, + name: "err_jwt_only", + authHeader: authHeader, mockArgs: mockArgs{ jwt: &jwtMockArgs{ token: token, @@ -83,9 +80,8 @@ func TestAuthProvidersAuth(t *testing.T) { wantErr: true, }, { - name: "ok_oidc_only", - authHeader: authHeader, - checkAPIToken: true, + name: "ok_oidc_only", + authHeader: authHeader, mockArgs: mockArgs{ oidc: &oidcMockArgs{ token: token, @@ -95,9 +91,8 @@ func TestAuthProvidersAuth(t *testing.T) { want: userName, }, { - name: "err_oidc_only", - authHeader: authHeader, - checkAPIToken: true, + name: "err_oidc_only", + authHeader: authHeader, mockArgs: mockArgs{ oidc: &oidcMockArgs{ token: token, @@ -107,15 +102,13 @@ func TestAuthProvidersAuth(t *testing.T) { wantErr: true, }, { - name: "err_no_providers", - authHeader: authHeader, - checkAPIToken: true, - wantErr: true, + name: "err_no_providers", + authHeader: authHeader, + wantErr: true, }, { - name: "err_jwt_ok_oidc", - authHeader: authHeader, - checkAPIToken: true, + name: "err_jwt_ok_oidc", + authHeader: authHeader, mockArgs: mockArgs{ jwt: &jwtMockArgs{ token: token, @@ -128,38 +121,6 @@ func TestAuthProvidersAuth(t *testing.T) { }, want: userName, }, - { - name: "ok_oidc_skip_check_api_token", - authHeader: authHeader, - checkAPIToken: false, - mockArgs: mockArgs{ - jwt: &jwtMockArgs{ - token: token, - jwtClaims: jwtClaims, - }, - oidc: &oidcMockArgs{ - token: token, - oidcToken: oidcToken, - }, - }, - want: userName, - }, - { - name: "err_oidc_skip_check_api_token", - authHeader: authHeader, - checkAPIToken: false, - mockArgs: mockArgs{ - jwt: &jwtMockArgs{ - token: token, - jwtClaims: jwtClaims, - }, - oidc: &oidcMockArgs{ - token: token, - err: err, - }, - }, - wantErr: true, - }, } for _, tCase := range tCases { @@ -172,10 +133,8 @@ func TestAuthProvidersAuth(t *testing.T) { authPrv := &AuthProviders{} if tCase.mockArgs.jwt != nil { jwtProvider := mock_auth.NewMockJWTProvider(ctrl) - if tCase.checkAPIToken { - jwtProvider.EXPECT().Verify(tCase.mockArgs.jwt.token). - Return(tCase.mockArgs.jwt.jwtClaims, tCase.mockArgs.jwt.err) - } + jwtProvider.EXPECT().Verify(tCase.mockArgs.jwt.token). + Return(tCase.mockArgs.jwt.jwtClaims, tCase.mockArgs.jwt.err) authPrv.JwtProvider = jwtProvider } @@ -187,7 +146,7 @@ func TestAuthProvidersAuth(t *testing.T) { authPrv.OidcProvider = oidcProvider } - got, err := authPrv.auth(context.Background(), authHeader, tCase.checkAPIToken) + got, err := authPrv.auth(context.Background(), authHeader) require.Equal(t, tCase.wantErr, err != nil) if tCase.wantErr { return diff --git a/internal/app/mw/grpc_mw.go b/internal/app/mw/grpc_mw.go index fa9b644..0b645ad 100644 --- a/internal/app/mw/grpc_mw.go +++ b/internal/app/mw/grpc_mw.go @@ -157,8 +157,7 @@ func GRPCAuthInterceptor(providers *AuthProviders) grpc.UnaryServerInterceptor { logger.Error("no authorization metadata provided") return nil, errUnauth } - _, checkAPIToken := tokenAuthServices[svc] - userName, err := providers.auth(ctx, authHeaderSlice[0], checkAPIToken) + userName, err := providers.auth(ctx, authHeaderSlice[0]) if err != nil { logger.Error("token auth failed", zap.Error(err)) return nil, errUnauth diff --git a/internal/app/mw/http_mw.go b/internal/app/mw/http_mw.go index 10aedcd..abf00d0 100644 --- a/internal/app/mw/http_mw.go +++ b/internal/app/mw/http_mw.go @@ -161,17 +161,8 @@ func HTTPAuthInterceptor(providers *AuthProviders) func(next http.Handler) http. return } - uriApi, _, _, err := parseURI(r.RequestURI) - if err != nil { - msg := "failed to parse URI" - logger.Error(msg, zap.Error(err)) - http.Error(w, msg, http.StatusInternalServerError) - return - } - authHeader := r.Header.Get("Authorization") - _, checkAPIToken := tokenAuthServices[uriApi] - username, err := providers.auth(ctx, authHeader, checkAPIToken) + username, err := providers.auth(ctx, authHeader) if err != nil { logger.Error("token auth failed", zap.Error(err)) http.Error(w, "Unauthenticated", http.StatusUnauthorized)