Implementing oidc authProvider for Authelia with react-oidc-context

I'm trying to add Authelia as an auth provider to my project. I'm currently trying to use the example for Keycloak from github to help me with the basic setup. I'm currently a bit confused as to how to integrate it. Authelia has its own login pages, and it requires a redirect url. I'm not sure which url that should be. In addition, I need to add some custom logic that will happen when logging in or out. I'm pulling data from Grafana based on the logged in user, and I need to initialize the grafana session so that the api calls will be authenticated correctly. What is the recommended approach for this scenario?
5 Replies
kapa.ai
kapa.ai2mo ago
Hi @Stormlight. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To implement an OIDC authProvider for Authelia with react-oidc-context in refine, you can follow a similar approach to the Keycloak example, but with some modifications. Here's a recommended approach based on the information available: 1. Set up react-oidc-context: First, you'll need to set up react-oidc-context with your Authelia configuration. This will handle the OIDC flow, including redirects. 2. Create a custom authProvider: Create a custom authProvider that integrates with react-oidc-context and includes your custom logic for Grafana. Here's a basic structure:
import { AuthProvider } from "@refinedev/core";
import { useAuth } from "react-oidc-context";

export const authProvider: AuthProvider = {
login: async () => {
// Trigger OIDC login
// This will redirect to Authelia's login page
return { success: true };
},
logout: async () => {
// Perform OIDC logout
// Add your custom Grafana logout logic here
return { success: true };
},
check: async () => {
// Check if the user is authenticated
// You can use react-oidc-context's useAuth hook here
const auth = useAuth();
return auth.isAuthenticated ? { authenticated: true } : { authenticated: false };
},
getIdentity: async () => {
// Get user identity from OIDC claims
const auth = useAuth();
return auth.user ? { id: auth.user.sub, name: auth.user.name } : null;
},
// Implement other methods as needed
};
import { AuthProvider } from "@refinedev/core";
import { useAuth } from "react-oidc-context";

export const authProvider: AuthProvider = {
login: async () => {
// Trigger OIDC login
// This will redirect to Authelia's login page
return { success: true };
},
logout: async () => {
// Perform OIDC logout
// Add your custom Grafana logout logic here
return { success: true };
},
check: async () => {
// Check if the user is authenticated
// You can use react-oidc-context's useAuth hook here
const auth = useAuth();
return auth.isAuthenticated ? { authenticated: true } : { authenticated: false };
},
getIdentity: async () => {
// Get user identity from OIDC claims
const auth = useAuth();
return auth.user ? { id: auth.user.sub, name: auth.user.name } : null;
},
// Implement other methods as needed
};
3. Configure the redirect URL: The redirect URL should be a route in your application that can handle the OIDC callback. You'll need to configure this in both your Authelia settings and your react-oidc-context configuration. 4. Add custom logic for Grafana: In your authProvider's login and logout methods, add the necessary logic to initialize or clear the Grafana session. 5. Use the authProvider in your Refine app:
import { Refine } from "@refinedev/core";
import { authProvider } from "./authProvider";

function App() {
return (
<Refine
authProvider={authProvider}
// ... other Refine configurations
>
{/* Your app components */}
</Refine>
);
}
import { Refine } from "@refinedev/core";
import { authProvider } from "./authProvider";

function App() {
return (
<Refine
authProvider={authProvider}
// ... other Refine configurations
>
{/* Your app components */}
</Refine>
);
}
For more detailed information on implementing custom auth providers in refine, you can refer to the Create Auth Provider tutorial (https://refine.dev/docs/guides-concepts/authentication/#oauth-integrations). Remember that you'll need to handle the OIDC flow, including token management and refreshing, which react-oidc-context can help with. You may also need to adjust your data provider to include the authentication token in API requests. For the specific integration with Authelia and Grafana, you might need to consult their respective documentation as the knowledge sources don't provide specific information about these integrations. Authentication Guide (https://refine.dev/docs/guides-concepts/authentication/) provides more general information about authentication in refine, which might be helpful for understanding the overall structure. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@453354981907759115> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
fascinating-indigo
fascinating-indigoOP2mo ago
@kapa.ai I currently have an issue where the <Authenticated> element never changes to true, even though the useAuth hook from react-oidc-context returns isAuthenticated true. When I look at the refine devtools, I see one call to useIsAuthenticated, and one to useGetIdentity. I don't see any return values for the queries. What might be causing this? Here is my "check" code: check: async () => { console.log("Checking auth..."); while (auth.isLoading) { await new Promise(resolve => setTimeout(resolve, 1000)); } try { console.log("user", auth.user); if (auth.user?.access_token) { return { authenticated: true, }; } return { authenticated: false, logout: true, redirectTo: "/login", error: { message: "Check failed", name: "Token not found", }, }; }
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the information you've provided and the knowledge sources available, it seems that there might be an issue with how the check method in your authProvider is implemented. Let's analyze the potential causes and suggest some solutions: 1. Asynchronous nature of the check method: The check method in the authProvider should return a promise that resolves immediately. Your current implementation with a while loop and setTimeout might be causing issues. The <Authenticated> component expects a quick response from the check method. 2. Dependency on auth object: It's not clear where the auth object is coming from in your check method. If it's from react-oidc-context, it should be used within a React component or a custom hook, not directly in the authProvider object. 3. Inconsistent return types: The check method should always return an object with the authenticated property, but your implementation might return undefined if an error occurs. Here's a suggested modification to your check method:
check: async () => {
console.log("Checking auth...");
try {
const auth = useAuth(); // This should be moved to a React component or custom hook
if (auth.isAuthenticated && auth.user?.access_token) {
return {
authenticated: true,
};
}
return {
authenticated: false,
logout: true,
redirectTo: "/login",
error: {
message: "Check failed",
name: "Not authenticated",
},
};
} catch (error) {
return {
authenticated: false,
logout: true,
redirectTo: "/login",
error: {
message: "Check failed",
name: "Error during authentication check",
},
};
}
},
check: async () => {
console.log("Checking auth...");
try {
const auth = useAuth(); // This should be moved to a React component or custom hook
if (auth.isAuthenticated && auth.user?.access_token) {
return {
authenticated: true,
};
}
return {
authenticated: false,
logout: true,
redirectTo: "/login",
error: {
message: "Check failed",
name: "Not authenticated",
},
};
} catch (error) {
return {
authenticated: false,
logout: true,
redirectTo: "/login",
error: {
message: "Check failed",
name: "Error during authentication check",
},
};
}
},
Additionally, make sure that you're providing a unique key prop to your <Authenticated> components. This has been reported to solve similar issues in the past, as mentioned in the Github issue comments (https://github.com/refinedev/refine/issues/4782):
<Authenticated key="uniqueKey">
{/* Your authenticated content */}
</Authenticated>
<Authenticated key="uniqueKey">
{/* Your authenticated content */}
</Authenticated>
If you're still experiencing issues, it might be helpful to check the following: 1. Ensure that your authProvider is correctly passed to the <Refine> component. 2. Check if there are any errors in the console that might provide more information. 3. Verify that the useAuth hook from react-oidc-context is working correctly in other parts of your application. If the problem persists, you might want to create a minimal reproducible example and open a new issue on the refine GitHub repository for more specific assistance. Authentication Components (https://refine.dev/docs/authentication/components/authenticated/) provides more information about the <Authenticated> component and its usage in refine. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@453354981907759115> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?