diff --git a/src/assets/images/orcid.png b/src/assets/images/orcid.png
new file mode 100644
index 0000000000000000000000000000000000000000..2db382dfc069b8a098c876a8d38add9977bc406a
Binary files /dev/null and b/src/assets/images/orcid.png differ
diff --git a/src/components/FunctionalArea/Modal/AccessDeniedModal/AccessDeniedModal.component.tsx b/src/components/FunctionalArea/Modal/AccessDeniedModal/AccessDeniedModal.component.tsx
index fc5ec255d90bf6f7ae1cefdd56539e85c1bbf7db..2cd0b46b08fd232978af3fe8db18240334b1ec0e 100644
--- a/src/components/FunctionalArea/Modal/AccessDeniedModal/AccessDeniedModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/AccessDeniedModal/AccessDeniedModal.component.tsx
@@ -7,6 +7,7 @@ import { MINUS_ONE, ZERO } from '@/constants/common';
 import { Button } from '@/shared/Button';
 import { adminEmailValSelector } from '@/redux/configuration/configuration.selectors';
 import { projectsSelector } from '@/redux/projects/projects.selectors';
+import { getOAuth } from '@/redux/oauth/oauth.thunks';
 
 export const AccessDeniedModal: React.FC = () => {
   const dispatch = useAppDispatch();
@@ -28,6 +29,7 @@ export const AccessDeniedModal: React.FC = () => {
 
   const handleLogin = async (e: React.FormEvent<HTMLButtonElement>): Promise<void> => {
     e.preventDefault();
+    dispatch(getOAuth());
     dispatch(openLoginModal());
   };
 
diff --git a/src/components/FunctionalArea/Modal/LoginModal/LoginModal.component.tsx b/src/components/FunctionalArea/Modal/LoginModal/LoginModal.component.tsx
index 3fa89a01282b34bd7a1dec3b1b3698f260ea16c8..58e6e2f672b5120cb8a691f118352b34c12e6307 100644
--- a/src/components/FunctionalArea/Modal/LoginModal/LoginModal.component.tsx
+++ b/src/components/FunctionalArea/Modal/LoginModal/LoginModal.component.tsx
@@ -7,6 +7,10 @@ import { Button } from '@/shared/Button';
 import { Input } from '@/shared/Input';
 import Link from 'next/link';
 import React from 'react';
+import { BASE_API_URL } from '@/constants';
+import { orcidEndpointSelector } from '@/redux/oauth/oauth.selectors';
+import Image from 'next/image';
+import orcidLogoImg from '@/assets/images/orcid.png';
 
 export const LoginModal: React.FC = () => {
   const dispatch = useAppDispatch();
@@ -14,11 +18,19 @@ export const LoginModal: React.FC = () => {
   const isPending = loadingUser === 'pending';
   const [credentials, setCredentials] = React.useState({ login: '', password: '' });
 
+  const orcidEndpoint = useAppSelector(orcidEndpointSelector);
+
+  const isOrcidAvailable = orcidEndpoint !== undefined;
+
   const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
     const { name, value } = e.target;
     setCredentials(prevCredentials => ({ ...prevCredentials, [name]: value }));
   };
 
+  const handleLoginViaOrcid = (): void => {
+    window.location.href = `${BASE_API_URL}/..${orcidEndpoint}`;
+  };
+
   const handleSubmit = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
     e.preventDefault();
     await dispatch(login(credentials));
@@ -57,6 +69,16 @@ export const LoginModal: React.FC = () => {
             Forgot password?
           </Link>
         </div>
+        {isOrcidAvailable && (
+          <Button
+            variantStyles="quiet"
+            className="mb-1 w-full justify-center text-base font-medium"
+            onClick={handleLoginViaOrcid}
+          >
+            <Image src={orcidLogoImg} alt="orcid logo" height={32} width={32} className="mr-1.5" />
+            Sign in with Orcid
+          </Button>
+        )}
         <Button
           type="submit"
           className="w-full justify-center text-base font-medium"
diff --git a/src/components/FunctionalArea/TopBar/User/User.component.test.tsx b/src/components/FunctionalArea/TopBar/User/User.component.test.tsx
index 6198869f43d302eedd7269fe183e1622eed445a3..707e0f5dac4dac4709f7d47e1eef9e5ee3e226ba 100644
--- a/src/components/FunctionalArea/TopBar/User/User.component.test.tsx
+++ b/src/components/FunctionalArea/TopBar/User/User.component.test.tsx
@@ -8,6 +8,7 @@ import { apiPath } from '@/redux/apiPath';
 import { HttpStatusCode } from 'axios';
 import mockRouter from 'next-router-mock';
 import { projectFixture } from '@/models/fixtures/projectFixture';
+import { oauthFixture } from '@/models/fixtures/oauthFixture';
 import { User } from './User.component';
 
 const mockedAxiosClient = mockNetworkResponse();
@@ -131,6 +132,8 @@ describe('AuthenticatedUser component', () => {
   });
 
   it('should display login modal if switch account is pressed', async () => {
+    mockedAxiosClient.onGet(apiPath.getOauthProviders()).reply(HttpStatusCode.Ok, oauthFixture);
+
     const { store } = renderComponent({
       user: {
         ...USER_INITIAL_STATE_MOCK,
diff --git a/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts b/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts
index dd5b22725de0bb9da3a296a43d2597c62e7e4c4a..f1c0f845b995fe380cd750a38acbf3d7b874631b 100644
--- a/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts
+++ b/src/components/FunctionalArea/TopBar/User/hooks/useUserActions.ts
@@ -8,6 +8,7 @@ import { useRouter } from 'next/router';
 import { USER_ROLE } from '@/constants/user';
 import { useMemo } from 'react';
 import { CURRENT_PROJECT_ADMIN_PANEL_URL } from '@/constants';
+import { getOAuth } from '@/redux/oauth/oauth.thunks';
 import { ADMIN_CURATOR_ACTIONS, BASE_ACTIONS } from '../User.constants';
 
 type UseUserActionsReturnType = {
@@ -33,6 +34,7 @@ export const useUserActions = (): UseUserActionsReturnType => {
   }, [userRole]);
 
   const openModalLogin = (): void => {
+    dispatch(getOAuth());
     dispatch(openLoginModal());
   };
 
diff --git a/src/models/fixtures/oauthFixture.ts b/src/models/fixtures/oauthFixture.ts
new file mode 100644
index 0000000000000000000000000000000000000000..753b8da35f060089663aadb518d34b7bee7b1b4e
--- /dev/null
+++ b/src/models/fixtures/oauthFixture.ts
@@ -0,0 +1,8 @@
+import { ZOD_SEED } from '@/constants';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { createFixture } from 'zod-fixture';
+import { oauthSchema } from '@/models/oauthSchema';
+
+export const oauthFixture = createFixture(oauthSchema, {
+  seed: ZOD_SEED,
+});
diff --git a/src/models/oauthSchema.ts b/src/models/oauthSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a9370c9d2876ad0aa7fff55142461c9b9b7dcea7
--- /dev/null
+++ b/src/models/oauthSchema.ts
@@ -0,0 +1,5 @@
+import { z } from 'zod';
+
+export const oauthSchema = z.object({
+  Orcid: z.string().optional(),
+});
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index 22f16e77a7483b0fdd2f86ce20aaee85bc1f5c2f..8227bfec287407fd9cc09415b7176beb6ed914bb 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -101,6 +101,7 @@ export const apiPath = {
   user: (login: string): string => `users/${login}`,
   getStacktrace: (code: string): string => `stacktrace/${code}`,
   submitError: (): string => `minervanet/submitError`,
+  getOauthProviders: (): string => `oauth/providers/`,
   userPrivileges: (login: string): string => `users/${login}?columns=privileges`,
   getComments: (): string => `projects/${PROJECT_ID}/comments/models/*/`,
   addComment: (modelId: number, x: number, y: number): string =>
diff --git a/src/redux/oauth/oauth.constants.ts b/src/redux/oauth/oauth.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fc92f1da5ab570919841515581dd6be8a4988ea2
--- /dev/null
+++ b/src/redux/oauth/oauth.constants.ts
@@ -0,0 +1 @@
+export const OAUTH_FETCHING_ERROR_PREFIX = 'Failed to fetch oauth providers';
diff --git a/src/redux/oauth/oauth.fixtures.ts b/src/redux/oauth/oauth.fixtures.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5b8212184250c69c348ce5fae7c8ac8392a914b8
--- /dev/null
+++ b/src/redux/oauth/oauth.fixtures.ts
@@ -0,0 +1,5 @@
+import { OAuth } from '@/types/models';
+
+export const initialOAuthFixture: OAuth = {
+  Orcid: undefined,
+};
diff --git a/src/redux/oauth/oauth.mock.ts b/src/redux/oauth/oauth.mock.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b1b18f8f02b1e79c503f6729793a82721cbf956e
--- /dev/null
+++ b/src/redux/oauth/oauth.mock.ts
@@ -0,0 +1,10 @@
+import { DEFAULT_ERROR } from '@/constants/errors';
+import { OauthState } from '@/redux/oauth/oauth.types';
+import { initialOAuthFixture } from '@/redux/oauth/oauth.fixtures';
+
+export const OAUTH_INITIAL_STATE_MOCK: OauthState = {
+  data: initialOAuthFixture,
+  loading: 'idle',
+  error: DEFAULT_ERROR,
+  orcidEndpoint: undefined,
+};
diff --git a/src/redux/oauth/oauth.reducers.ts b/src/redux/oauth/oauth.reducers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e5cce6516930ce2c66cfc37c86b864a6ff8f740
--- /dev/null
+++ b/src/redux/oauth/oauth.reducers.ts
@@ -0,0 +1,20 @@
+import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
+import { OauthState } from '@/redux/oauth/oauth.types';
+import { getOAuth } from '@/redux/oauth/oauth.thunks';
+
+export const getOauthReducer = (builder: ActionReducerMapBuilder<OauthState>): void => {
+  builder.addCase(getOAuth.pending, state => {
+    state.loading = 'pending';
+  });
+  builder.addCase(getOAuth.fulfilled, (state, action) => {
+    state.data = action.payload || undefined;
+    if (action.payload && action.payload.Orcid) {
+      state.orcidEndpoint = action.payload.Orcid;
+    }
+    state.loading = 'succeeded';
+  });
+  builder.addCase(getOAuth.rejected, state => {
+    state.loading = 'failed';
+    // TODO to discuss manage state of failure
+  });
+};
diff --git a/src/redux/oauth/oauth.selectors.ts b/src/redux/oauth/oauth.selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8bda1780c56eb0804cfbc0e53935a6d6e492fc0d
--- /dev/null
+++ b/src/redux/oauth/oauth.selectors.ts
@@ -0,0 +1,6 @@
+import { createSelector } from '@reduxjs/toolkit';
+import { rootSelector } from '../root/root.selectors';
+
+export const oauthSelector = createSelector(rootSelector, state => state.oauth);
+
+export const orcidEndpointSelector = createSelector(oauthSelector, oauth => oauth?.orcidEndpoint);
diff --git a/src/redux/oauth/oauth.slice.ts b/src/redux/oauth/oauth.slice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8abb3ba8feb2a9b9414d529710cdbfc367f402ca
--- /dev/null
+++ b/src/redux/oauth/oauth.slice.ts
@@ -0,0 +1,21 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { OauthState } from '@/redux/oauth/oauth.types';
+import { getOauthReducer } from '@/redux/oauth/oauth.reducers';
+
+const initialState: OauthState = {
+  data: undefined,
+  loading: 'idle',
+  error: { name: '', message: '' },
+  orcidEndpoint: undefined,
+};
+
+const oauthSlice = createSlice({
+  name: 'oauth',
+  initialState,
+  reducers: {},
+  extraReducers: builder => {
+    getOauthReducer(builder);
+  },
+});
+
+export default oauthSlice.reducer;
diff --git a/src/redux/oauth/oauth.thunks.ts b/src/redux/oauth/oauth.thunks.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42907946419bc86ca8befe0794a16661aec26da7
--- /dev/null
+++ b/src/redux/oauth/oauth.thunks.ts
@@ -0,0 +1,24 @@
+import { axiosInstance } from '@/services/api/utils/axiosInstance';
+import { OAuth } from '@/types/models';
+import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
+import { createAsyncThunk } from '@reduxjs/toolkit';
+import { ThunkConfig } from '@/types/store';
+import { getError } from '@/utils/error-report/getError';
+import { oauthSchema } from '@/models/oauthSchema';
+import { OAUTH_FETCHING_ERROR_PREFIX } from '@/redux/oauth/oauth.constants';
+import { apiPath } from '../apiPath';
+
+export const getOAuth = createAsyncThunk<OAuth | undefined, void, ThunkConfig>(
+  'oauth/getProviders',
+  async () => {
+    try {
+      const response = await axiosInstance.get<OAuth>(apiPath.getOauthProviders());
+
+      const isDataValid = validateDataUsingZodSchema(response.data, oauthSchema);
+
+      return isDataValid ? response.data : undefined;
+    } catch (error) {
+      return Promise.reject(getError({ error, prefix: OAUTH_FETCHING_ERROR_PREFIX }));
+    }
+  },
+);
diff --git a/src/redux/oauth/oauth.types.ts b/src/redux/oauth/oauth.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2992b701903eca04a3792cfed87a85b5388ca170
--- /dev/null
+++ b/src/redux/oauth/oauth.types.ts
@@ -0,0 +1,9 @@
+import { OAuth } from '@/types/models';
+import { Loading } from '@/types/loadingState';
+
+export type OauthState = {
+  orcidEndpoint: string | undefined;
+  data: OAuth | undefined;
+  loading: Loading;
+  error: Error;
+};
diff --git a/src/redux/root/root.fixtures.ts b/src/redux/root/root.fixtures.ts
index 0f6962d29a1615c73c2fbb6de27a929e8a20d3a5..421151bd9d870052cc5137a3f66f7c3451b494e8 100644
--- a/src/redux/root/root.fixtures.ts
+++ b/src/redux/root/root.fixtures.ts
@@ -1,5 +1,6 @@
 import { CONSTANT_INITIAL_STATE } from '@/redux/constant/constant.adapter';
 import { PROJECTS_STATE_INITIAL_MOCK } from '@/redux/projects/projects.mock';
+import { OAUTH_INITIAL_STATE_MOCK } from '@/redux/oauth/oauth.mock';
 import { COMMENT_INITIAL_STATE_MOCK } from '@/redux/comment/comment.mock';
 import { BACKGROUND_INITIAL_STATE_MOCK } from '../backgrounds/background.mock';
 import { BIOENTITY_INITIAL_STATE_MOCK } from '../bioEntity/bioEntity.mock';
@@ -39,6 +40,7 @@ export const INITIAL_STORE_STATE_MOCK: RootState = {
   backgrounds: BACKGROUND_INITIAL_STATE_MOCK,
   drawer: drawerInitialStateMock,
   map: initialMapStateFixture,
+  oauth: OAUTH_INITIAL_STATE_MOCK,
   overlays: OVERLAYS_INITIAL_STATE_MOCK,
   reactions: REACTIONS_STATE_INITIAL_MOCK,
   configuration: CONFIGURATION_INITIAL_STATE,
diff --git a/src/redux/store.ts b/src/redux/store.ts
index e7649c165cbd19dc9ef1d42ba807fddec7172518..ebc65642cab5db9e0a830989779bdaaceec80450 100644
--- a/src/redux/store.ts
+++ b/src/redux/store.ts
@@ -10,6 +10,7 @@ import drugsReducer from '@/redux/drugs/drugs.slice';
 import mapReducer from '@/redux/map/map.slice';
 import modalReducer from '@/redux/modal/modal.slice';
 import modelsReducer from '@/redux/models/models.slice';
+import oauthReducer from '@/redux/oauth/oauth.slice';
 import overlayBioEntityReducer from '@/redux/overlayBioEntity/overlayBioEntity.slice';
 import overlaysReducer from '@/redux/overlays/overlays.slice';
 import projectReducer from '@/redux/project/project.slice';
@@ -65,6 +66,7 @@ export const reducers = {
   plugins: pluginsReducer,
   markers: markersReducer,
   entityNumber: entityNumberReducer,
+  oauth: oauthReducer,
 };
 
 export const middlewares = [mapListenerMiddleware.middleware, errorListenerMiddleware.middleware];
diff --git a/src/types/models.ts b/src/types/models.ts
index 044d36d8983998a08941364dedcffa28287990a6..c55955ac291dc9571cd2879f730777ebb663682e 100644
--- a/src/types/models.ts
+++ b/src/types/models.ts
@@ -64,6 +64,7 @@ import { z } from 'zod';
 import { commentSchema } from '@/models/commentSchema';
 import { userSchema } from '@/models/userSchema';
 import { javaStacktraceSchema } from '@/models/javaStacktraceSchema';
+import { oauthSchema } from '@/models/oauthSchema';
 
 export type Project = z.infer<typeof projectSchema>;
 export type OverviewImageView = z.infer<typeof overviewImageView>;
@@ -133,3 +134,5 @@ export type PageOf<T> = {
   number: number;
   content: T[];
 };
+
+export type OAuth = z.infer<typeof oauthSchema>;