diff --git a/gatsby-node.ts b/gatsby-node.ts index dee554d2..7c7fa6b0 100644 --- a/gatsby-node.ts +++ b/gatsby-node.ts @@ -197,7 +197,6 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { isPermanent: true, force: true, }); - createRedirect({ fromPath: '/how-to/*', toPath: '/verify/how-to/:splat', @@ -210,6 +209,66 @@ export const createPages: GatsbyNode['createPages'] = ({ actions }) => { isPermanent: true, force: true, }); + createRedirect({ + fromPath: '/verify/getting-started/overview/*', + toPath: '/verify/how-it-works/overview/:splat', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/articles/custom-ui-css', + toPath: '/verify/guides/custom-styling/#custom-css-adding-a-stylesheet', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify', + toPath: '/verify/getting-started/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/articles/custom-ui-css', + toPath: '/verify/guides/custom-styling/#custom-css-adding-a-stylesheet', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/guides/test-users/', + toPath: '/verify/getting-started/test-users/', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/overview/*', + toPath: '/verify/how-it-works/overview/:splat', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/basics/*', + toPath: '/verify/how-it-works/core-concepts/:splat', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/oidc-intro/*', + toPath: '/verify/how-it-works/oidc-intro/:splat', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/getting-started/best-security-practices/*', + toPath: '/verify/how-it-works/best-security-practices/:splat', + isPermanent: true, + force: true, + }); + createRedirect({ + fromPath: '/verify/guides/production/*', + toPath: '/verify/getting-started/production/:splat', + isPermanent: true, + force: true, + }); }; // https://www.gatsbyjs.com/docs/conceptual/data-fetching/#source-data-to-be-queried-at-build-time diff --git a/src/Homepage/SignaturesIntegrationCards.tsx b/src/Homepage/SignaturesIntegrationCards.tsx index 5b89fe7f..8c3c94f3 100644 --- a/src/Homepage/SignaturesIntegrationCards.tsx +++ b/src/Homepage/SignaturesIntegrationCards.tsx @@ -1,9 +1,9 @@ import React, { ReactElement } from 'react'; import { LogoCard } from '../components/LogoCard/LogoCard'; -import PythonLogo from './logos/integrations/python.svg'; -import NodejsLogo from './logos/integrations/nodejs.svg'; -import PhpLogo from './logos/integrations/php.svg'; -import CsharpLogo from './logos/integrations/csharp.svg'; +import PythonLogo from '../images/logos/integrations/python.svg'; +import NodejsLogo from '../images/logos/integrations/nodejs.svg'; +import PhpLogo from '../images/logos/integrations/php.svg'; +import CsharpLogo from '../images/logos/integrations/csharp.svg'; const guides = [ { diff --git a/src/Homepage/eIDCards.tsx b/src/Homepage/eIDCards.tsx index c052c15d..3ebf6913 100644 --- a/src/Homepage/eIDCards.tsx +++ b/src/Homepage/eIDCards.tsx @@ -1,14 +1,14 @@ import React, { ReactElement } from 'react'; import { LogoCard } from '../components/LogoCard/LogoCard'; -import MitIDLogo from './logos/eids/mitid.svg'; -import NoBankIDLogo from './logos/eids/no-bankid.svg'; -import SeBankIDLogo from './logos/eids/se-bankid.svg'; -import FtnLogo from './logos/eids/ftn.svg'; -import FrejaIDLogo from './logos/eids/freja.svg'; -import VippsLogo from './logos/eids/vipps.svg'; -import iDinLogo from './logos/eids/idin.svg'; -import MitIDErhvervLogo from './logos/eids/mitid-erhverv.svg'; -import PersonalausweisLogo from './logos/eids/personalausweis.svg'; +import MitIDLogo from '../images/logos/eids/mitid.svg'; +import NoBankIDLogo from '../images/logos/eids/no-bankid.svg'; +import SeBankIDLogo from '../images/logos/eids/se-bankid.svg'; +import FtnLogo from '../images/logos/eids/ftn.svg'; +import FrejaIDLogo from '../images/logos/eids/freja.svg'; +import VippsLogo from '../images/logos/eids/vipps.svg'; +import iDinLogo from '../images/logos/eids/idin.svg'; +import MitIDErhvervLogo from '../images/logos/eids/mitid-erhverv.svg'; +import PersonalausweisLogo from '../images/logos/eids/personalausweis.svg'; const eids = [ { diff --git a/src/components/AuthorizeURLBuilder.tsx b/src/components/AuthorizeURLBuilder.tsx index acc9b82a..f051225f 100644 --- a/src/components/AuthorizeURLBuilder.tsx +++ b/src/components/AuthorizeURLBuilder.tsx @@ -485,10 +485,7 @@ export default function AuthorizeURLBuilder(props: { helpText={ Also known as{' '} - + callback URL . diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index 24a5275e..df9e06bc 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -18,6 +18,7 @@ const VERIFY_CATEGORIES = [ 'eIDs', 'Guides & Tools', 'Integrations', + 'How it works', 'Reference', ]; diff --git a/src/Homepage/VerifyIntegrationCards.tsx b/src/components/VerifyIntegrationCards.tsx similarity index 54% rename from src/Homepage/VerifyIntegrationCards.tsx rename to src/components/VerifyIntegrationCards.tsx index ef4f7714..55d2923c 100644 --- a/src/Homepage/VerifyIntegrationCards.tsx +++ b/src/components/VerifyIntegrationCards.tsx @@ -1,116 +1,134 @@ import React, { ReactElement } from 'react'; -import { LogoCard } from '../components/LogoCard/LogoCard'; +import { LogoCard } from './LogoCard/LogoCard'; -import Auth0Logo from './logos/integrations/auth0.svg'; -import JavaScriptLogo from './logos/integrations/javascript.svg'; -import ReactLogo from './logos/integrations/react.svg'; -import NodejsLogo from './logos/integrations/nodejs.svg'; -import VuejsLogo from './logos/integrations/vuejs.svg'; -import ExpoLogo from './logos/integrations/expo.svg'; -import WordpressLogo from './logos/integrations/wordpress.svg'; -import AwsCognitoLogo from './logos/integrations/aws-cognito.svg'; -import FirebaseLogo from './logos/integrations/firebase.svg'; -import OktaLogo from './logos/integrations/okta.svg'; -import PingFederateLogo from './logos/integrations/ping-identity.svg'; -import PhpLogo from './logos/integrations/php.svg'; -import DotnetLogo from './logos/integrations/dotnet.svg'; -import OneLoginLogo from './logos/integrations/onelogin.svg'; -import KotlinLogo from './logos/integrations/kotlin.svg'; -import SwiftLogo from './logos/integrations/swift.svg'; +import Auth0Logo from '../images/logos/integrations/auth0.svg'; +import JavaScriptLogo from '../images/logos/integrations/javascript.svg'; +import ReactLogo from '../images/logos/integrations/react.svg'; +import NodejsLogo from '../images/logos/integrations/nodejs.svg'; +import VuejsLogo from '../images/logos/integrations/vuejs.svg'; +import ExpoLogo from '../images/logos/integrations/expo.svg'; +import WordpressLogo from '../images/logos/integrations/wordpress.svg'; +import AwsCognitoLogo from '../images/logos/integrations/aws-cognito.svg'; +import FirebaseLogo from '../images/logos/integrations/firebase.svg'; +import OktaLogo from '../images/logos/integrations/okta.svg'; +import PingFederateLogo from '../images/logos/integrations/ping-identity.svg'; +import PhpLogo from '../images/logos/integrations/php.svg'; +import DotnetLogo from '../images/logos/integrations/dotnet.svg'; +import OneLoginLogo from '../images/logos/integrations/onelogin.svg'; +import KotlinLogo from '../images/logos/integrations/kotlin.svg'; +import SwiftLogo from '../images/logos/integrations/swift.svg'; const guides = [ { href: 'react', header: 'React', logo: { src: ReactLogo, width: 46, alt: 'React logo' }, + category: 'SPA/Native', }, { href: 'javascript', header: 'JavaScript', logo: { src: JavaScriptLogo, alt: 'JavaScript logo' }, + category: 'SPA/Native', }, { href: 'nodejs-express', header: 'Node.js (Express)', logo: { src: NodejsLogo, width: 70, height: 42, alt: 'Node.js (Express) logo' }, + category: 'Web', }, { href: 'vuejs', header: 'Vue.js', logo: { src: VuejsLogo, height: 46, alt: 'Vue.js logo' }, + category: 'SPA/Native', }, { href: 'kotlin', header: 'Kotlin (Android)', logo: { src: KotlinLogo, alt: 'Kotlin logo' }, + category: 'SPA/Native', }, { href: 'react-native-expo', header: 'Expo (React Native)', logo: { src: ExpoLogo, height: 42, width: 38, alt: 'Expo logo' }, + category: 'SPA/Native', }, { href: 'swift', header: 'Swift (iOS)', logo: { src: SwiftLogo, alt: 'Swift logo' }, + category: 'SPA/Native', }, { href: 'wordpress', header: 'Wordpress', logo: { src: WordpressLogo, width: 42, height: 42, alt: 'Wordpress logo' }, + category: 'Web', }, { href: 'auth0', header: 'Auth0', logo: { src: Auth0Logo, height: 36, alt: 'Auth0 logo' }, + category: 'CIAM', }, { href: 'aws-cognito', header: 'AWS Cognito', logo: { src: AwsCognitoLogo, width: 38, height: 44, alt: 'AWS Cognito logo' }, + category: 'CIAM', }, { href: 'firebase', header: 'Firebase', logo: { src: FirebaseLogo, width: 32, height: 44, alt: 'Firebase logo' }, + category: 'CIAM', }, { href: 'okta', header: 'Okta', logo: { src: OktaLogo, width: 69, height: 23, alt: 'Okta logo' }, + category: 'CIAM', }, { href: 'onelogin', header: 'OneLogin', logo: { src: OneLoginLogo, width: 42, height: 42, alt: 'OneLogin logo' }, + category: 'CIAM', }, { href: 'pingfederate', header: 'PingFederate', logo: { src: PingFederateLogo, alt: 'PingFederate logo' }, + category: 'CIAM', }, { href: 'PHP', header: 'PHP', logo: { src: PhpLogo, width: 64, height: 34, alt: 'PHP logo' }, + category: 'Web', }, { href: 'aspnet-core-v6', header: 'ASP.NET Core 6.0', logo: { src: DotnetLogo, alt: 'Dotnet logo' }, + category: 'Web', }, { href: 'aspnet-core-v3', header: 'ASP.NET Core 3.1', logo: { src: DotnetLogo, alt: 'Dotnet logo' }, + category: 'Web', }, ]; -export function VerifyIntegrationCards(): ReactElement { +function IntegrationCardsList({ category }: { category?: string }): ReactElement { + const displayGuides = category ? guides.filter(g => g.category === category) : guides; return (
- {guides.map(guide => ( + {displayGuides.map(guide => ( ); } + +export const VerifyIntegrationCards = () => ; +export const VerifyIntegrationCardsWeb = () => ; +export const VerifyIntegrationCardsSpa = () => ; +export const VerifyIntegrationCardsCiam = () => ; diff --git a/src/Homepage/logos/eids/freja.svg b/src/images/logos/eids/freja.svg similarity index 100% rename from src/Homepage/logos/eids/freja.svg rename to src/images/logos/eids/freja.svg diff --git a/src/Homepage/logos/eids/ftn.svg b/src/images/logos/eids/ftn.svg similarity index 100% rename from src/Homepage/logos/eids/ftn.svg rename to src/images/logos/eids/ftn.svg diff --git a/src/Homepage/logos/eids/idin.svg b/src/images/logos/eids/idin.svg similarity index 100% rename from src/Homepage/logos/eids/idin.svg rename to src/images/logos/eids/idin.svg diff --git a/src/Homepage/logos/eids/mitid-erhverv.svg b/src/images/logos/eids/mitid-erhverv.svg similarity index 100% rename from src/Homepage/logos/eids/mitid-erhverv.svg rename to src/images/logos/eids/mitid-erhverv.svg diff --git a/src/Homepage/logos/eids/mitid.svg b/src/images/logos/eids/mitid.svg similarity index 100% rename from src/Homepage/logos/eids/mitid.svg rename to src/images/logos/eids/mitid.svg diff --git a/src/Homepage/logos/eids/no-bankid.svg b/src/images/logos/eids/no-bankid.svg similarity index 100% rename from src/Homepage/logos/eids/no-bankid.svg rename to src/images/logos/eids/no-bankid.svg diff --git a/src/Homepage/logos/eids/personalausweis.svg b/src/images/logos/eids/personalausweis.svg similarity index 100% rename from src/Homepage/logos/eids/personalausweis.svg rename to src/images/logos/eids/personalausweis.svg diff --git a/src/Homepage/logos/eids/se-bankid.svg b/src/images/logos/eids/se-bankid.svg similarity index 100% rename from src/Homepage/logos/eids/se-bankid.svg rename to src/images/logos/eids/se-bankid.svg diff --git a/src/Homepage/logos/eids/vipps.svg b/src/images/logos/eids/vipps.svg similarity index 100% rename from src/Homepage/logos/eids/vipps.svg rename to src/images/logos/eids/vipps.svg diff --git a/src/Homepage/logos/integrations/auth0.svg b/src/images/logos/integrations/auth0.svg similarity index 100% rename from src/Homepage/logos/integrations/auth0.svg rename to src/images/logos/integrations/auth0.svg diff --git a/src/Homepage/logos/integrations/aws-cognito.svg b/src/images/logos/integrations/aws-cognito.svg similarity index 100% rename from src/Homepage/logos/integrations/aws-cognito.svg rename to src/images/logos/integrations/aws-cognito.svg diff --git a/src/Homepage/logos/integrations/csharp.svg b/src/images/logos/integrations/csharp.svg similarity index 100% rename from src/Homepage/logos/integrations/csharp.svg rename to src/images/logos/integrations/csharp.svg diff --git a/src/Homepage/logos/integrations/dotnet.svg b/src/images/logos/integrations/dotnet.svg similarity index 100% rename from src/Homepage/logos/integrations/dotnet.svg rename to src/images/logos/integrations/dotnet.svg diff --git a/src/Homepage/logos/integrations/expo.svg b/src/images/logos/integrations/expo.svg similarity index 100% rename from src/Homepage/logos/integrations/expo.svg rename to src/images/logos/integrations/expo.svg diff --git a/src/Homepage/logos/integrations/firebase.svg b/src/images/logos/integrations/firebase.svg similarity index 100% rename from src/Homepage/logos/integrations/firebase.svg rename to src/images/logos/integrations/firebase.svg diff --git a/src/Homepage/logos/integrations/javascript.svg b/src/images/logos/integrations/javascript.svg similarity index 100% rename from src/Homepage/logos/integrations/javascript.svg rename to src/images/logos/integrations/javascript.svg diff --git a/src/Homepage/logos/integrations/kotlin.svg b/src/images/logos/integrations/kotlin.svg similarity index 100% rename from src/Homepage/logos/integrations/kotlin.svg rename to src/images/logos/integrations/kotlin.svg diff --git a/src/Homepage/logos/integrations/nodejs.svg b/src/images/logos/integrations/nodejs.svg similarity index 100% rename from src/Homepage/logos/integrations/nodejs.svg rename to src/images/logos/integrations/nodejs.svg diff --git a/src/Homepage/logos/integrations/okta.svg b/src/images/logos/integrations/okta.svg similarity index 100% rename from src/Homepage/logos/integrations/okta.svg rename to src/images/logos/integrations/okta.svg diff --git a/src/Homepage/logos/integrations/onelogin.svg b/src/images/logos/integrations/onelogin.svg similarity index 100% rename from src/Homepage/logos/integrations/onelogin.svg rename to src/images/logos/integrations/onelogin.svg diff --git a/src/Homepage/logos/integrations/php.png b/src/images/logos/integrations/php.png similarity index 100% rename from src/Homepage/logos/integrations/php.png rename to src/images/logos/integrations/php.png diff --git a/src/Homepage/logos/integrations/php.svg b/src/images/logos/integrations/php.svg similarity index 100% rename from src/Homepage/logos/integrations/php.svg rename to src/images/logos/integrations/php.svg diff --git a/src/Homepage/logos/integrations/ping-identity.svg b/src/images/logos/integrations/ping-identity.svg similarity index 100% rename from src/Homepage/logos/integrations/ping-identity.svg rename to src/images/logos/integrations/ping-identity.svg diff --git a/src/Homepage/logos/integrations/python.svg b/src/images/logos/integrations/python.svg similarity index 100% rename from src/Homepage/logos/integrations/python.svg rename to src/images/logos/integrations/python.svg diff --git a/src/Homepage/logos/integrations/react.svg b/src/images/logos/integrations/react.svg similarity index 100% rename from src/Homepage/logos/integrations/react.svg rename to src/images/logos/integrations/react.svg diff --git a/src/Homepage/logos/integrations/swift.svg b/src/images/logos/integrations/swift.svg similarity index 100% rename from src/Homepage/logos/integrations/swift.svg rename to src/images/logos/integrations/swift.svg diff --git a/src/Homepage/logos/integrations/vuejs.svg b/src/images/logos/integrations/vuejs.svg similarity index 100% rename from src/Homepage/logos/integrations/vuejs.svg rename to src/images/logos/integrations/vuejs.svg diff --git a/src/Homepage/logos/integrations/wordpress.svg b/src/images/logos/integrations/wordpress.svg similarity index 100% rename from src/Homepage/logos/integrations/wordpress.svg rename to src/images/logos/integrations/wordpress.svg diff --git a/src/pages/index.mdx b/src/pages/index.mdx index 9921284e..4a84700a 100644 --- a/src/pages/index.mdx +++ b/src/pages/index.mdx @@ -4,7 +4,7 @@ subtitle: Welcome to the API documentation for Idura Verify & Idura Document Sig --- import { ProductCards } from '../Homepage/ProductCards'; -import { VerifyIntegrationCards } from '../Homepage/VerifyIntegrationCards'; +import { VerifyIntegrationCards } from '../components/VerifyIntegrationCards'; import { SignaturesIntegrationCards } from '../Homepage/SignaturesIntegrationCards'; import { EidCards } from '../Homepage/eIDCards'; import { DeveloperToolsCards } from '../Homepage/DeveloperToolsCards'; @@ -15,7 +15,7 @@ import { DeveloperToolsCards } from '../Homepage/DeveloperToolsCards'; ## Integrate Idura Verify -Idura Verify can be integrated with any tech stack using the standard [OpenID Connect (OIDC) protocol](/verify/getting-started/oidc-intro/). +Idura Verify can be integrated with any tech stack using the standard [OpenID Connect (OIDC) protocol](/verify/how-it-works/oidc-intro/). You don't need to be an identity expert to integrate Idura: a trusted OIDC client library or one of our dedicated SDKs will handle most of the complexity for you. Idura can also easily connect to your existing CIAM system, such as Auth0, AWS Cognito, or Firebase. diff --git a/src/pages/verify/getting-started/dashboard-setup.mdx b/src/pages/verify/getting-started/dashboard-setup.mdx new file mode 100644 index 00000000..5d27c2f0 --- /dev/null +++ b/src/pages/verify/getting-started/dashboard-setup.mdx @@ -0,0 +1,65 @@ +--- +product: verify +category: Getting Started +sort: 1 +title: Set up the Dashboard +subtitle: Create a tenant, register an application, and generate client credentials. +--- + +Before you can integrate Idura Verify into your application, you need to configure your environment in the Idura Dashboard. +This takes about two minutes and will give you the client credentials required to build your own eID-based login flows. + +## Create a tenant + +A [tenant](/verify/how-it-works/core-concepts/#tenants) represents your organization's isolated environment at Idura. + +1. [Sign up for a free test account](https://dashboard.idura.app/signup) to access the Idura Dashboard. +2. You will be prompted to create your first tenant. + + + **Risk-free testing**: Your free account includes a sandbox environment with unlimited test + logins, allowing you to build and test your integration without any obligations or unexpected + costs. + + +## Register a domain + +Everything you do with Idura requires a [domain](/verify/how-it-works/core-concepts/#domains) to route your authentication requests. + +1. Go to the [**Domains** tab](https://dashboard.idura.app/domains) in your dashboard. +2. Click **Register domain**. +3. Select your domain type. We recommend starting with a standard `.test.idura.broker` domain for your local development and testing. +4. Type your domain name in the **Domain settings** field. If your company name is Acme Corp, your first domain may look somethig like `acme-corp.test.idura.broker`. + +## Register an application + +An [application](/verify/how-it-works/core-concepts/#applications) represents the software you are building (e.g., your React frontend or Node.js backend). +Registering an application generates the client credentials you will use in your code to configure your software to communicate with Idura Verify. + +1. Add a [new login application](https://dashboard.idura.app/applications/add/) from the **Applications** tab of your dashboard. +2. Configure your new application: + +- **Name:** Choose a recognizable name. +- **Domain:** Select the domain you registered in the previous step. +- **Client ID / Realm:** You can use the auto-generated identifier (e.g., `urn:my:application:identifier:123`) or create a custom one. +- **Redirect URL(s):** Enter the [callback URL](/verify/reference/glossary/#redirect-uri) where Idura should send users after they log in (e.g., `http://localhost:3000/api/auth/callback` for local development). + _Note: Wildcards are not supported, but you can always add more URLs to the list._ +- **Application Type:** Select the option that matches your tech stack (e.g., Single Page Application -> React, Regular Web Application -> Node.js). This will point you to the right integration guide once the application is created. + +3. Click **Create Application** to save the initial configurations. + Your application settings will now display the **Client ID / Realm**. You will need to paste it in your code once ready to integrate. + +### Generate a client secret + +import GenerateClientSecretSnippet from '../../../snippets/generate-client-secret.mdx'; + + + +## What's next? + +Your dashboard is configured and your API credentials are ready to use. + +To be able to run test logins, you need to create a test user for the eID(s) you're planning to use. +Note that you can't use your real, personal eID in a test environment. + +[Create test users →](/verify/getting-started/test-users/) diff --git a/src/pages/verify/getting-started/index.mdx b/src/pages/verify/getting-started/index.mdx index 677a72fb..a2ba130c 100644 --- a/src/pages/verify/getting-started/index.mdx +++ b/src/pages/verify/getting-started/index.mdx @@ -2,55 +2,66 @@ product: verify category: Getting Started sort: 0 -title: Get started with Idura Verify +title: Getting Started +subtitle: A quickstart guide to get up and running with Idura Verify. Follow the steps below to authenticate your first user. --- -import { isIndexPage } from '../../../utils'; - -import { graphql as gatsbyGraphql, Link } from 'gatsby'; -export const pageQuery = gatsbyGraphql` - query GettingStarted { - pages: allMdx( - filter: { - frontmatter: { - product: { eq: "verify" } - category: { eq: "Getting Started" } - } - } - sort: {frontmatter: {sort: ASC}} - ) { - edges { - node { - __typename - id - frontmatter { - title - category - subtitle - } - fields { - slug - } - internal { - contentFilePath - } - } - } - } - } -`; - -Below you will find a list of topics to get you started with Idura Verify: - -
    - {props.data.pages.edges - .map(edge => edge.node) - .filter(node => !isIndexPage(node)) - .map(node => ( -
  • - {node.frontmatter.title} -
    - {node.frontmatter.subtitle} -
  • - ))} -
+import { + VerifyIntegrationCardsWeb, + VerifyIntegrationCardsSpa, + VerifyIntegrationCardsCiam, +} from '../../../components/VerifyIntegrationCards'; + +## Step 1: Set up the Dashboard + +Before writing any code, you need to create a tenant and register your own Idura domain and application to get your API credentials. + +[Set up the Dashboard →](/verify/getting-started/dashboard-setup/) +Learn how to navigate the Idura Dashboard, register a tenant, and create your first domain and application. + +## Step 2: Create a test user + +You cannot use your real, personal eID to test integrations in a development environment. Instead, national eID schemes require dummy accounts for testing. + +[Create test users →](/verify/getting-started/test-users/) +Learn how to generate test identities for the eIDs you'll be working with. + +## Step 3: Choose your integration + +Ready to build? We provide SDKs and step-by-step guides to integrate Idura Verify into your existing tech stack. Select your framework below. + +### SPA & Native + + + +### Backend & Web + + + +### Identity platforms + + + +### Not ready to write code yet? + +You can simulate a full authentication flow right from your browser using our developer tools: + +- [Authorize URL Builder →](/verify/guides/authorize-url-builder/) Construct and test specific login requests, tuning the parameters to your needs. +- [OIDC Visualizer →](/verify/guides/oidc-visualizer/) Step through a complete login flow. Inspect requests and responses exchanged during the process, decode JWT tokens, and review user claims returned by the eID. + +Or build your knowledge first by exploring our resources: + +- [Understand OpenID Connect →](/verify/how-it-works/oidc-intro/) Learn about the different OpenID Connect flows supported by Idura Verify, authorization request parameters, JWT tokens, and more. +- [Review security best practices →](/verify/how-it-works/best-security-practices/) See guidelines for securing your implementation and choosing the right OIDC flow for your application architecture. + +## Step 4: Move to production + +Once your integration is working locally with test users, it's time to upgrade. + +- [Get ready for production →](/verify/getting-started/production/) Review our checklist for applying for eIDs you need and going live. + + + We recommend starting the [application + process](/verify/getting-started/production/#ordering-production-eids) as early as possible. + Approval and certificate issuance can take several business days depending on the eID provider. + diff --git a/src/pages/verify/getting-started/production.mdx b/src/pages/verify/getting-started/production.mdx new file mode 100644 index 00000000..27e77f2a --- /dev/null +++ b/src/pages/verify/getting-started/production.mdx @@ -0,0 +1,55 @@ +--- +product: verify +category: Getting Started +sort: 3 +title: Get ready for production +subtitle: Upgrade your account, apply for eIDs, and go live. +--- + +Once your integration is working locally with test users, you are ready to move to production. + + + **A paid subscription is required.** To accept real eID logins and set up a production domain, you + must upgrade your free test account to a paid plan. + + +## Moving to production + +1. **Upgrade your subscription.** + Go to the [**Billing** tab](https://dashboard.idura.app/billing) in the Idura Dashboard and choose a plan that suits your expected usage. + +2. **Apply for production eIDs.** + Using real national eIDs requires formal approval and production certificates from the respective national authorities. + + + + + +**Ordering eIDs for production** + +Each eID provider has specific requirements. Use the links below to review the necessary steps for each provider. + +- [FrejaID](/verify/e-ids/frejaid/#ordering-frejaid) +- [Swedish BankID](/verify/e-ids/swedish-bankid/#ordering-swedish-bankid) +- [Norwegian BankID](/verify/e-ids/norwegian-bankid/#ordering-norwegian-bankid) +- [German Personalausweis](/verify/e-ids/german-personalausweis/#getting-ready-for-production) +- [Vipps MobilePay](/verify/e-ids/vipps-mobilepay/#ordering-vipps-mobilepay) +- [Danish MitID](/verify/e-ids/danish-mitid/#order-mitid-for-production) +- [Finnish Trust Network](/verify/e-ids/finnish-trust-network/#ordering-a-production-agreement) +- [Dutch iDIN](/verify/e-ids/dutch-idin/#ordering-idin) + +**We recommend starting the application process as early as possible. Approval and certificate +issuance can take several business days depending on the eID provider.** + + + +3. **Set up your production environment.** + - Change the environment from **Test** to **Production** in the top left corner of your Idura Dashboard. + - Go to the **Domains** tab and create a production domain. + _Note that if you choose a domain that ends with something other than `idura.broker`, we recommend going with the Idura-managed option (**Managed SSL certificate**) for SSL certificate._ + - Go to the **Applications** tab and register your production application. + _The **Client ID** of your production application must be unique._ + +4. **Update your codebase.** + Configure your website or application with the new production domain and API credentials. + You are now ready to accept real eID logins in your production application! Run a quick test with a real eID to verify everything is working as expected. diff --git a/src/pages/verify/getting-started/test-users.mdx b/src/pages/verify/getting-started/test-users.mdx new file mode 100644 index 00000000..b42c0f92 --- /dev/null +++ b/src/pages/verify/getting-started/test-users.mdx @@ -0,0 +1,24 @@ +--- +product: verify +category: Getting Started +sort: 2 +title: Create test users +subtitle: Generate sandbox identities to test your eID integrations in development. +--- + +import TestUsersSetupLinks from '../../../snippets/test-users-setup-instructions'; + +To run test logins with most eIDs, you'll need to create a test user and install a test app. +Find instructions for each eID in the links below. + + + +## What's next? + +Once your [dashboard is configured](/verify/getting-started/dashboard-setup/) and test users are ready, choose your path forward: + +- **[Choose your integration →](/verify/integrations/)** Ready to start building? Find SDKs and follow the step-by-step guides for your tech stack. +- **[Understand OpenID Connect →](/verify/how-it-works/oidc-intro/)** + Not ready to write code yet? Learn about supported OIDC flows and security best practices. +- **[Get ready for production →](/verify/getting-started/production/)** + Already built and tested your integration locally? Review our checklist for upgrading your account and applying for real eIDs. diff --git a/src/pages/verify/guides/caller-authentication.mdx b/src/pages/verify/guides/caller-authentication.mdx index 52e77886..6792cb7a 100644 --- a/src/pages/verify/guides/caller-authentication.mdx +++ b/src/pages/verify/guides/caller-authentication.mdx @@ -15,7 +15,7 @@ This creates a secure, phishing-resistant way to confirm who you are talking to ## The CIBA flow -Caller Authentication is built on the [**Client-Initiated Backchannel Authentication (CIBA) flow**](/verify/getting-started/oidc-intro/#authenticate-with-ciba). +Caller Authentication is built on the [**Client-Initiated Backchannel Authentication (CIBA) flow**](/verify/how-it-works/oidc-intro/#authenticate-with-ciba). With CIBA, the client application provides a hint (e.g. the user's SSN) that triggers an authentication request to the user's device. The user can then approve the request and complete the authentication process on their device. diff --git a/src/pages/verify/guides/oidc-visualizer.mdx b/src/pages/verify/guides/oidc-visualizer.mdx index 20f48593..4cd8030d 100644 --- a/src/pages/verify/guides/oidc-visualizer.mdx +++ b/src/pages/verify/guides/oidc-visualizer.mdx @@ -22,7 +22,7 @@ and **Idura Verify acting as the Authorization Server**, so you can understand w ## Authorization Code Flow -[Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) is the most common OIDC flow for web applications. +[Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) is the most common OIDC flow for web applications. The diagram below shows how the Client Application and Authorization Server interact to complete this flow. ![Authorization Code Flow ](./images/authorization_code_flow_diagram.png) diff --git a/src/pages/verify/guides/production.mdx b/src/pages/verify/guides/production.mdx deleted file mode 100644 index 43cc3682..00000000 --- a/src/pages/verify/guides/production.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -product: verify -category: Guides & Tools -sort: 1 -title: Get ready for production ---- - -Once you have developed and tested your application to work with test user accounts, you are ready to move ahead and work with real user eID accounts. - -_Please note_ that for production usage, you need a paid subscription. - -Follow these steps to get ready for production: - -1. If you haven't done so already, go to [dashboard.idura.app](https://dashboard.idura.app/billing), select the **Billing** tab, and choose a plan that suits your expected usage. -2. Next, you must acquire a production certificate for the eID provider(s) you plan to use in production. - - - - - -**Ordering eIDs for production** - -Each eID provider has specific requirements. Use the links below to review the necessary steps for each provider. - -- [Swedish BankID](/verify/e-ids/swedish-bankid/#ordering-swedish-bankid) -- [Norwegian BankID](/verify/e-ids/norwegian-bankid/#ordering-norwegian-bankid) -- [Vipps MobilePay](/verify/e-ids/vipps-mobilepay/#ordering-vipps-mobilepay) -- [Danish MitID](/verify/e-ids/danish-mitid/#order-mitid-for-production) -- [Finnish Trust Network](/verify/e-ids/finnish-trust-network/#ordering-a-production-agreement) - - - -3. Change the environment from **Test** to **Production** on the top left corner of the Dashboard. -4. Go to the **Domains** tab and set up a production domain. - - Note that if you choose a domain that ends with something other than `idura.broker`, we recommend going with the Idura-managed option ("Managed SSL certificate") for SSL certificate. -5. Go to the **Applications** tab and register your production application: - - The **Client ID** must be unique; it cannot be the same as any of your other applications -6. Configure your website or application with the new domain, Client ID, and Client secret. - -Once you have been through these steps, you are ready to start using real Swedish BankID, Danish MitID, and others in your production application. diff --git a/src/pages/verify/guides/pushed-authorization-requests.mdx b/src/pages/verify/guides/pushed-authorization-requests.mdx index 2858204d..96a2015a 100644 --- a/src/pages/verify/guides/pushed-authorization-requests.mdx +++ b/src/pages/verify/guides/pushed-authorization-requests.mdx @@ -5,9 +5,12 @@ sort: 1 title: Pushed Authorization Requests (PAR) --- -Pushed Authorization Requests (PAR) -is an OAuth 2.0 extension that allows sending [authorization request parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters) -to the authorization server via a POST request, rather than in the browser's URL query string. + + Pushed Authorization Requests (PAR) + +is an OAuth 2.0 extension that allows sending [authorization request +parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters) to the authorization +server via a POST request, rather than in the browser's URL query string. PAR enhances security by mitigating risks associated with exposing sensitive data in URLs. It also allows the authorization server to authenticate the client and validate the request early in the process (before any user interaction occurs), @@ -16,12 +19,12 @@ which can prevent attempts to spoof clients or otherwise tamper with or misuse a Using PAR improves [Telemetry & Observability](/verify/guides/telemetry/#par) for your Idura applications: it helps you trace authorization requests by giving you a `Trace-Id` to follow immediately and directly to your backend. -PAR can be used with any [OpenID Connect flow](/verify/getting-started/oidc-intro/#supported-openid-connect-flows) that involves authorization requests sent via the browser, -including the [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) and the [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce). +PAR can be used with any [OpenID Connect flow](/verify/how-it-works/oidc-intro/#supported-openid-connect-flows) that involves authorization requests sent via the browser, +including the [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) and the [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce). ## How PAR works -[Regular authorization requests](/verify/getting-started/glossary/#authorization-request-authorize-url) are made by redirecting the user's browser to the OAuth2 authorization endpoint (`/oauth2/authorize`) with all parameters included in the URL. +[Regular authorization requests](/verify/reference/glossary/#authorization-request-authorize-url) are made by redirecting the user's browser to the OAuth2 authorization endpoint (`/oauth2/authorize`) with all parameters included in the URL. The process with PAR is slightly different: @@ -37,23 +40,23 @@ You can start using PAR in place of standard authorization requests by following ### 1: Push the authorization request from your backend Send a POST request from your backend to the PAR endpoint. The PAR endpoint URL can be found in your -[OIDC Discovery Document](/verify/getting-started/glossary/#oidc-discovery-document-well-knownopenid-configuration) under `pushed_authorization_request_endpoint`. +[OIDC Discovery Document](/verify/reference/glossary/#oidc-discovery-document-well-knownopenid-configuration) under `pushed_authorization_request_endpoint`. Your POST request should include: - The same parameters you would normally send in an authorization request (e.g. `response_type`, `scope`, `redirect_uri`, `state`). - For the complete list of authorization request parameters, see [Authorize Request Parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters). -- Client authentication credentials (for [confidential clients](/verify/getting-started/glossary/#confidential-client)): + For the complete list of authorization request parameters, see [Authorize Request Parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters). +- Client authentication credentials (for [confidential clients](/verify/reference/glossary/#confidential-client)): - either `client_id` and `client_secret` (included in the Basic Authorization header) or - `client_assertion` and `client_assertion_type` (included in the request body), when using [Private Key JWT](/verify/guides/privatekey-jwt/). -- `code_challenge` and `code_challenge_method` (for [public clients](/verify/getting-started/glossary/#public-clients) or clients implementing [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce)). +- `code_challenge` and `code_challenge_method` (for [public clients](/verify/reference/glossary/#public-clients) or clients implementing [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)). -The [PKCE](/verify/getting-started/glossary/#pkce-proof-key-for-code-exchange) extension to the Authorization Code Flow is required for public clients and recommended for confidential clients. +The [PKCE](/verify/reference/glossary/#pkce-proof-key-for-code-exchange) extension to the Authorization Code Flow is required for public clients and recommended for confidential clients. It offers stronger protection against the misuse or injection of authorization codes, making your implementation more secure. -For more details, see [OpenID Connect best security practices](/verify/getting-started/best-security-practices/verify/getting-started/best-security-practices/#authorization-code-flow). +For more details, see [OpenID Connect best security practices](/verify/how-it-works/best-security-practices/#authorization-code-flow). diff --git a/src/pages/verify/guides/test-users.mdx b/src/pages/verify/guides/test-users.mdx deleted file mode 100644 index b0739b96..00000000 --- a/src/pages/verify/guides/test-users.mdx +++ /dev/null @@ -1,13 +0,0 @@ ---- -product: verify -category: Guides & Tools -sort: 0 -title: Creating test users -subtitle: How to create test users and set up test apps for different eIDs ---- -import TestUsersSetupLinks from '../../../snippets/test-users-setup-instructions'; - -To run test logins with most eIDs, you'll need to create a test user and install a test app. -Find instructions for each eID in the links below. - - diff --git a/src/pages/verify/getting-started/best-security-practices.mdx b/src/pages/verify/how-it-works/best-security-practices.mdx similarity index 81% rename from src/pages/verify/getting-started/best-security-practices.mdx rename to src/pages/verify/how-it-works/best-security-practices.mdx index cb5ee1fe..704be5e4 100644 --- a/src/pages/verify/getting-started/best-security-practices.mdx +++ b/src/pages/verify/how-it-works/best-security-practices.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 3 title: OpenID Connect best security practices subtitle: Learn about key security guidelines for implementing basic OpenID Connect authentication in client applications. @@ -15,9 +15,9 @@ Idura Verify is an OpenID Provider, handling most of the process. However, it is ## Authorization Code Flow -The most secure method of performing OIDC authentication is the [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow), or its extended version — [Authorization Code Flow with PKCE](/verify/getting-started/oidc-intro/#authenticate-with-pkce). +The most secure method of performing OIDC authentication is the [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow), or its extended version — [Authorization Code Flow with PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce). -In the Authorization Code Flow, the client application exchanges an authorization code for tokens at the token endpoint. When using Idura Verify for eID authentication: After the end user successfully logs in with their [eID](/verify/e-ids) and is redirected back to the client application through the redirect URL, the client application retrieves the authorization code from the URL. The client application then uses this code to request an ID token from Idura Verify (see [code for token exchange](/verify/getting-started/oidc-intro/#exchange-the-code-for-a-token)). +In the Authorization Code Flow, the client application exchanges an authorization code for tokens at the token endpoint. When using Idura Verify for eID authentication: After the end user successfully logs in with their [eID](/verify/e-ids) and is redirected back to the client application through the redirect URL, the client application retrieves the authorization code from the URL. The client application then uses this code to request an ID token from Idura Verify (see [code for token exchange](/verify/how-it-works/oidc-intro/#exchange-the-code-for-a-token)). The Authorization Code Flow enhances security by mitigating replay attempts by attackers (when an attacker tries to reuse a valid intercepted token) and generally reduces the attack surface since ID tokens are not exposed in URLs. @@ -27,15 +27,15 @@ The Authorization Code Flow enhances security by mitigating replay attempts by a - Confidential clients — such as traditional server-based web applications – are encouraged to use the **PKCE flow** as well. This is a recommended approach, since **PKCE** provides strong protection against misuse and injection of authorization codes, making it a more secure option. - Alternatively, confidential clients can implement the **Authorization Code Flow**. - Confidential clients implementing the **Authorization Code Flow** (without **PKCE**) should take additional precautions, such as using the `nonce` parameter and the respective claim in the `id_token`, and one-time tokens carried in the `state` parameter. -- For use cases where authentication is initiated on one device but completed on another (e.g., a call center agent starts the authentication process for the end user), the back-channel [CIBA flow](/verify/getting-started/oidc-intro/#authenticate-with-ciba) is the right choice. -- The Implicit Flow is obsolete and [should not be used in production applications](/verify/getting-started/best-security-practices/#avoid-implicit-flow). +- For use cases where authentication is initiated on one device but completed on another (e.g., a call center agent starts the authentication process for the end user), the back-channel [CIBA flow](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) is the right choice. +- The Implicit Flow is obsolete and [should not be used in production applications](/verify/how-it-works/best-security-practices/#avoid-implicit-flow). ## Pushed Authorization Requests In a standard authorization request, parameters are sent in a URI query string via a browser redirect. This approach has several limitations: - There’s no inherent cryptographic guarantee that the data hasn’t been tampered with or forged. For example, an attacker could try modifying the `scope` or `redirect_uri` parameters, potentially gaining unauthorized access or redirecting users to an unintended endpoint. -- Request parameters are exposed in URLs, which can leak to web server logs or other sites. This is particularly risky if [personally identifiable information (PII)](/verify/getting-started/glossary/#personally-identifiable-information-pii) is included. +- Request parameters are exposed in URLs, which can leak to web server logs or other sites. This is particularly risky if [personally identifiable information (PII)](/verify/reference/glossary/#personally-identifiable-information-pii) is included. - Authorization request URLs can become quite large, which may cause errors in request processing. [Pushed Authorization Requests (PAR)](/verify/guides/pushed-authorization-requests/) address these issues by allowing clients to send authorization request parameters in a **POST request directly from the backend** to the authorization server. @@ -51,11 +51,11 @@ Replacing regular authorization requests with PAR is a simple upgrade that helps `nonce` is used to associate an ID token to the specific authorization request and user session. -The client application should bind `nonce` to the user agent session and send it with the initial [authorization request](/verify/getting-started/oidc-intro/#example-authorization-url) to the OpenID Provider. The binding is done using HTTPOnly, Secure cookies, and preferably with a server-side encrypted value for the `nonce` (using authenticated encryption). -The OpenID Provider puts the received `nonce` value into the `id_token` that is issued as part of the [code exchange](/verify/getting-started/oidc-intro/#exchange-the-code-for-a-token) at the token endpoint. +The client application should bind `nonce` to the user agent session and send it with the initial [authorization request](/verify/how-it-works/oidc-intro/#example-authorization-url) to the OpenID Provider. The binding is done using HTTPOnly, Secure cookies, and preferably with a server-side encrypted value for the `nonce` (using authenticated encryption). +The OpenID Provider puts the received `nonce` value into the `id_token` that is issued as part of the [code exchange](/verify/how-it-works/oidc-intro/#exchange-the-code-for-a-token) at the token endpoint. -- `nonce` serves as a [token validation](/verify/getting-started/best-security-practices/#always-validating-jwts) parameter. If an attacker injects an authorization code in the authorization response, the `nonce` value in the client session and the `nonce` value in the `id_token` received from the token endpoint will not match, and the attack will be detected. -- `nonce` also helps protect against an attacker potentially intercepting a valid [`state` parameter](/verify/getting-started/best-security-practices/#the-state-parameter), but then providing a `code` value tied to a different session. This could be a concern for public clients, and, in theory, in some confidential client scenarios. +- `nonce` serves as a [token validation](/verify/how-it-works/best-security-practices/#always-validating-jwts) parameter. If an attacker injects an authorization code in the authorization response, the `nonce` value in the client session and the `nonce` value in the `id_token` received from the token endpoint will not match, and the attack will be detected. +- `nonce` also helps protect against an attacker potentially intercepting a valid [`state` parameter](/verify/how-it-works/best-security-practices/#the-state-parameter), but then providing a `code` value tied to a different session. This could be a concern for public clients, and, in theory, in some confidential client scenarios. **Best practice:** For confidential clients implementing the Authorization Code Flow, it is strongly recommended to always include a `nonce` parameter in authorization requests to protect against misuse of authorization codes. The client application should then validate the `nonce` in the received `id_token`, and not use any issued tokens until this check has succeeded. @@ -65,7 +65,7 @@ _For public clients using the PKCE flow, the `nonce` parameter can also provide The `state` parameter helps prevent Cross-Site Request Forgery (CSRF) attacks by maintaining state between the client application and the authorization server. -When initiating an [authorization request](<(/verify/getting-started/oidc-intro/#example-authorization-url)>), the client application generates a random value and includes it in the `state` parameter. +When initiating an [authorization request](/verify/how-it-works/oidc-intro/#example-authorization-url), the client application generates a random value and includes it in the `state` parameter. This random value links the request to the redirect URL to the client session. Once the user is authenticated, the authorization server redirects the user back to the client application's redirect URL, including the same `state` value in the URL. For example: `https://your-app.com/callback?code=authorization-code&state=unique-state-value` Similarly, if the `state` parameter was included in the authorization request, the error responses from the authorization server will also contain the `state` parameter, providing protection against attacker-forged error responses. @@ -77,7 +77,7 @@ Overall, the `state` parameter allows the client application to verify that the ## Always validating JWTs Upon successful user authentication, Idura Verify will issue an **[ID token](/verify/reference/token-contents/)** to the client application. `id_token` contains user authentication information in the form of a JSON Web Token (JWT). -However, receiving a JWT is not enough - your application must also [validate it](/verify/getting-started/oidc-intro/#validate-the-jwt). Without validation, there’s no guarantee that the token hasn’t been tampered with or forged. +However, receiving a JWT is not enough - your application must also [validate it](/verify/how-it-works/oidc-intro/#validate-the-jwt). Without validation, there’s no guarantee that the token hasn’t been tampered with or forged. _Note: `id_token` must be validated, even if using the `/userInfo` endpoint for personal data._ diff --git a/src/pages/verify/getting-started/basics.mdx b/src/pages/verify/how-it-works/core-concepts.mdx similarity index 74% rename from src/pages/verify/getting-started/basics.mdx rename to src/pages/verify/how-it-works/core-concepts.mdx index 44af79a6..25056028 100644 --- a/src/pages/verify/getting-started/basics.mdx +++ b/src/pages/verify/how-it-works/core-concepts.mdx @@ -1,32 +1,34 @@ --- product: verify -category: Getting Started +category: How it works sort: 1 -title: Learn the Basics +title: Core concepts subtitle: Learn the basics of Idura and familiarize yourself with the terminology. --- This document explains some of the basic terminology we use at Idura, and we try to relate these terms to concepts you are already familiar with. -This article introduces the following core concepts of Idura: **[Tenants](/verify/getting-started/basics/#tenants)**, **[Domains](/verify/getting-started/basics/#domains)**, **[Applications](/verify/getting-started/basics/#applications)**, and **[eID Providers](/verify/getting-started/basics/#eid-providers)**. +This article introduces the following core concepts of Idura: **[Tenants](/verify/how-it-works/core-concepts/#tenants)**, **[Domains](/verify/how-it-works/core-concepts/#domains)**, **[Applications](/verify/how-it-works/core-concepts/#applications)**, and **[eID Providers](/verify/how-it-works/core-concepts/#eid-providers)**. One important distinction in Idura Verify is the separation of **Test** and **Production**. Inside each tenant, you may toggle the setup between Test and Production to configure each environment separately. -To set up a production domain you must first upgrade your free subscription to a paid subscription.   +_Note: To set up a production domain, you must first upgrade your free subscription to a paid subscription._ -For illustration purposes, we will use a fictitious company named _Secure Insurance_ that wants to use Idura for authentication. They have both a web and a mobile application, and they want their users to be able to log in with Swedish BankID and Danish MitID. +For illustration purposes, we will use a fictitious company named Secure Insurance that wants to use Idura for authentication. They have both a web and a mobile application, and they want their users to be able to log in with Swedish BankID and Danish MitID. ## Tenants If you haven't already [signed up](https://dashboard.idura.app/signup?utm_source=docs) for an Idura account, feel free - it's free. -When you sign up for the first time, you will be asked to create your first tenant and your first _domain_ along with it. In Idura, a tenant is the **logical isolation unit** that isolates you and your data from other Idura tenants. The term describes a software architecture where a single instance of the software serves multiple tenants. No tenant can access the instance of another tenant, even though the software may be running on the same machine. +In Idura, a tenant is the **logical isolation unit** that isolates you and your data from other Idura tenants. +The term describes a software architecture where a single instance of the software serves multiple tenants. +No tenant can access the instance of another tenant, even though the software may be running on the same machine. -Tenant characteristics: +**Tenant characteristics:** - The tenant name has to be unique. It is used primarily for your reference and communication purposes and carries no formal significance. - The tenant name can be changed at any time after creation. @@ -36,15 +38,14 @@ You can create additional tenants at any time. To do so, go to the upper-right c ## Domains -As discussed in the previous section, when you create a new account with Idura, you also create your first domain. Typically, your first domain would be something like `secure-insurance-test.idura.broker`. - A domain in Idura Verify is the DNS domain on which you call our service to perform authentication. +Typically, your first domain would be something like `secure-insurance-test.idura.broker`. -Domains are registered for either test or production and as such determine whether you can use test eID accounts or real, live eID accounts. +Domains are registered for either test or production and determine whether you can use test user identities or real eID accounts. -As such, **the domain is the key distinction between test and production.** +As such, **the domain is the key distinction between Test and Production.** @@ -89,7 +90,3 @@ In most cases, this is handled through the intermediary of Idura, although in so More detail on the formalities and process can be found in the section about [eIDs](/verify/e-ids/). - -## Where to go from here - -This section introduced several core concepts of Idura. Next, we recommend learning [how Idura supports the OpenID Connect protocol](/verify/getting-started/oidc-intro/) and reviewing [best security practices for implementing OpenID Connect authentication](/verify/getting-started/best-security-practices/) in client applications. diff --git a/src/pages/verify/getting-started/oidc-intro.mdx b/src/pages/verify/how-it-works/oidc-intro.mdx similarity index 94% rename from src/pages/verify/getting-started/oidc-intro.mdx rename to src/pages/verify/how-it-works/oidc-intro.mdx index 6e6712e0..dbe9aea7 100644 --- a/src/pages/verify/getting-started/oidc-intro.mdx +++ b/src/pages/verify/how-it-works/oidc-intro.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 2 title: Using OpenID Connect subtitle: Learn how Idura supports the OpenID Connect protocol. @@ -14,23 +14,23 @@ Idura Verify is an OpenID Provider. It is integrated through the authentication The OpenID Connect(OIDC) protocol defines different strategies (flows) to authenticate users. Idura Verify supports five different OpenID Connect flows: -#### [1. The Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) +#### [1. The Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) The Authorization Code Flow is used for traditional server-based web applications, also referred to as _confidential clients_. These applications can securely store a client secret and establish back-channel communication with the Idura Verify service. This facilitates a secure [code-for-token exchange](#exchange-the-code-for-a-token) during authentication. -#### [2. The PKCE Flow](/verify/getting-started/oidc-intro/#authenticate-with-pkce) +#### [2. The PKCE Flow](/verify/how-it-works/oidc-intro/#authenticate-with-pkce) The PKCE Flow (pronounced _pixy_) can be used by _public clients_ such as single-page applications (SPAs) and native applications that cannot keep a secret. With PKCE, a one-time secret is generated and used for the code exchange. -#### [3. The Implicit Flow](/verify/getting-started/oidc-intro/#authenticate-with-implicit-flow) +#### [3. The Implicit Flow](/verify/how-it-works/oidc-intro/#authenticate-with-implicit-flow) The Implicit Flow returns a token directly in the browser. Support for this flow is being discontinued, although it will continue to function on test domains for the foreseeable future for simpler debugging during development. -#### [4. The CIBA flow](/verify/getting-started/oidc-intro/#authenticate-with-ciba) +#### [4. The CIBA flow](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) The CIBA flow is designed for use cases where the client application isn't directly operated by the end-user but can trigger the authentication process on their behalf. A canonical example is a call center agent verifying a caller's identity. -#### [5. The Headless flow](/verify/getting-started/oidc-intro/#authenticate-with-headless) +#### [5. The Headless flow](/verify/how-it-works/oidc-intro/#authenticate-with-headless) The Headless flow is a custom protocol by Idura. It allows interacting with eIDs that offer a poll-based workflow, where a user agent redirect is not required. @@ -49,7 +49,7 @@ To begin the login flow, you will need to authenticate the user at the [eID Prov To authenticate the user, your app must send the user to the _OAuth2 authorization endpoint (`/oauth2/authorize`)_ with the appropriate set of parameters. -You can find the URL for the _OAuth2 authorization endpoint_ in the OpenID Connect Discovery Document exposed on your [Idura Verify Domain](/verify/getting-started/basics/#domains): +You can find the URL for the _OAuth2 authorization endpoint_ in the OpenID Connect Discovery Document exposed on your [Idura Verify Domain](/verify/how-it-works/core-concepts/#domains): ```http GET https://YOUR_SUBDOMAIN.idura.broker/.well-known/openid-configuration @@ -188,21 +188,21 @@ When adding login to your application, you will build the authorization URL (als You can try the above URL right now if you have a [test user for Norwegian BankID](/verify/e-ids/norwegian-bankid/#test-users). -Your next steps will depend on the [OpenID Connect flow type](/verify/getting-started/oidc-intro/#supported-openid-connect-flows) you're implementing. See the relevant section below for a description of how each flow unfolds: +Your next steps will depend on the [OpenID Connect flow type](/verify/how-it-works/oidc-intro/#supported-openid-connect-flows) you're implementing. See the relevant section below for a description of how each flow unfolds: -- [Authorization Code Flow](/verify/getting-started/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) -- [PKCE Flow](/verify/getting-started/oidc-intro/#authenticate-with-pkce) -- [Implicit Flow](/verify/getting-started/oidc-intro/#authenticate-with-implicit-flow) -- [CIBA](/verify/getting-started/oidc-intro/#authenticate-with-ciba) -- [Headless](/verify/getting-started/oidc-intro/#authenticate-headless) +- [Authorization Code Flow](/verify/how-it-works/oidc-intro/#authenticate-with-back-channel-authorization-code-flow) +- [PKCE Flow](/verify/how-it-works/oidc-intro/#authenticate-with-pkce) +- [Implicit Flow](/verify/how-it-works/oidc-intro/#authenticate-with-implicit-flow) +- [CIBA](/verify/how-it-works/oidc-intro/#authenticate-with-ciba) +- [Headless](/verify/how-it-works/oidc-intro/#authenticate-headless) -After completing the steps specific to your chosen flow, you can proceed to [validating the JWT](/verify/getting-started/oidc-intro/#validate-the-jwt) received from successful authentication. +After completing the steps specific to your chosen flow, you can proceed to [validating the JWT](/verify/how-it-works/oidc-intro/#validate-the-jwt) received from successful authentication. A more secure alternative to traditional authorization requests is [Pushed Authorization Requests (PAR)](/verify/guides/pushed-authorization-requests). -PAR lets you initiate the authentication flow by sending [authorization request parameters](/verify/getting-started/oidc-intro/#authorize-request-parameters) directly to the authorization server via a POST request. +PAR lets you initiate the authentication flow by sending [authorization request parameters](/verify/how-it-works/oidc-intro/#authorize-request-parameters) directly to the authorization server via a POST request. This approach keeps parameters out of URLs, making requests more secure and protecting their integrity. It also ensures sensitive data remains confidential – e.g. if you are including PII in a `login_hint`. [View the PAR implementation guide →](/verify/guides/pushed-authorization-requests/#implementing-par-with-idura) @@ -508,7 +508,7 @@ The validation step is required; without it, you cannot trust the contained end- We strongly recommend that you find a battle-hardened library for your specific platform to do this heavy lifting. You can find an extensive list of libraries on jwt.io. Alternatively, Idura provides a list of [integrations](/verify/integrations) that handle most of the authentication process, including JWT validation. -For more information, see [OpenID Connect security best practices](/verify/getting-started/best-security-practices/#always-validating-id-tokens) and JWT validation guide. +For more information, see [OpenID Connect security best practices](/verify/how-it-works/best-security-practices/#always-validating-id-tokens) and JWT validation guide. ## The 'scope' parameter diff --git a/src/pages/verify/getting-started/overview.mdx b/src/pages/verify/how-it-works/overview.mdx similarity index 94% rename from src/pages/verify/getting-started/overview.mdx rename to src/pages/verify/how-it-works/overview.mdx index 821fa791..d0ab08e5 100644 --- a/src/pages/verify/getting-started/overview.mdx +++ b/src/pages/verify/how-it-works/overview.mdx @@ -1,6 +1,6 @@ --- product: verify -category: Getting Started +category: How it works sort: 0 title: Idura Verify Overview --- @@ -11,11 +11,11 @@ Idura Verify provides eID authentication as a service. An **eID** is a special kind of online identity that is tied to a _natural person_. A natural person in relation to eID is a living, individual human being. Examples of eIDs are Danish MitID, Swedish BankID, and Dutch iDIN. -An eID may be used for authentication and in most cases also for digitally signing legal documents. +An eID may be used for authentication and, in most cases, for digitally signing legal documents. -An eID is different from traditional external identity sources such as Google or Facebook. Generally an online identity lifecycle has three main phases: +An eID is different from traditional external identity sources such as Google or Facebook. Generally, an online identity lifecycle has three main phases: 1. **Enrollment** consists of verification of the legal identity and subsequently the issuance of a digital identity. 2. **Active, day-to-day use** is the authentication of the user as the holder of the issued digital identity. diff --git a/src/pages/verify/index.mdx b/src/pages/verify/index.mdx index be45f92b..d8b029a2 100644 --- a/src/pages/verify/index.mdx +++ b/src/pages/verify/index.mdx @@ -1,23 +1,12 @@ ---- -product: verify -title: Use eID in your applications ---- +export const VerifyRedirect = () => { + const { useEffect } = require('react'); + const { navigate } = require('gatsby'); -For an introduction to Idura Verify and eID, you may want to read [the overview](/verify/getting-started/overview) in the Getting Started section. +useEffect(() => { +navigate('/verify/getting-started', { replace: true }); +}, []); -Idura Verify supports two distinct use cases supported by most eID solutions: +return null; +}; -**Authentication** - -All eID services supports user authentication. With Idura Verify, you integrate using _OpenID Connect_ (aka OIDC). A general introduction to OIDC with Idura Verify is available in the section on [Using OIDC](/verify/getting-started/oidc-intro). - -**Digital Signatures** - -Due to the underlying use of asymmetric encryption by some eID services, like the Norwegian and Swedish BankID, -digitally signing text is also supported through a proprietary Idura API. - -- SE BankID: offers signing via [specific OIDC parameters](/verify/e-ids/swedish-bankid/#signing-textmarkdown) -- NO BankID: More documentation on this will soon follow, - but we have an example of how to program both plain [text signing and PDF signing into your ASP.NET Core app](https://github.com/criipto/docs-old/blob/master/signatures/dotnet-core-v3.md#plain-text-signature) - -If you do not find the documentation you need, please do not hesitate to drop us a note at [support@idura.eu](mailto:support@idura.eu). +export default VerifyRedirect; diff --git a/src/pages/verify/integrations/firebase.mdx b/src/pages/verify/integrations/firebase.mdx index 7607992d..f75685dc 100644 --- a/src/pages/verify/integrations/firebase.mdx +++ b/src/pages/verify/integrations/firebase.mdx @@ -43,7 +43,7 @@ Alternatively, you can follow Firebase documentation for [web applications](http Click **Add new provider**, then select **OpenID Connect**. ![OIDC custom provider](./firebase/OIDC-custom-provider.png) 3. You will now enable and define a new OIDC provider using the [information from your Idura Dashboard and the Client Secret you previously saved](#firebase-application-and-oidc-provider-setup). -4. Choose the **Grant type** you intend to use. We recommend choosing **Code flow**. _For more information, see [OpenID Connect best security practices](/verify/getting-started/best-security-practices/#authorization-code-flow)._ +4. Choose the **Grant type** you intend to use. We recommend choosing **Code flow**. _For more information, see [OpenID Connect best security practices](/verify/how-it-works/best-security-practices/#authorization-code-flow)._ 5. Enter a provider name – this is entirely up to you. We used "Idura" in this example. 6. Enter your Idura Application **Client ID** in the **Client ID** field. 7. Enter your Idura domain in the **Issuer (URL)** field (e.g., `https://acme-corp.idura.broker`). diff --git a/src/pages/verify/reference/glossary.mdx b/src/pages/verify/reference/glossary.mdx index d9e33da0..49943ead 100644 --- a/src/pages/verify/reference/glossary.mdx +++ b/src/pages/verify/reference/glossary.mdx @@ -176,10 +176,12 @@ Mobile apps and single-page applications (SPAs) are public clients. As they cann ## R -### Redirect URI (Callback URL) +### Redirect URI -The URL in your application where the user's browser is redirected after authentication is complete (or has failed). -You have to register all redirect URIs in your Idura Application via the Dashboard. +A redirect URI (also known as a **callback URL** or **redirect URL**) is a URL in your [client application](/verify/reference/glossary/#application-client-application) +where the user's browser is redirected after the authentication process has completed. +Following to the [OpenID Connect Core specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest), Idura does not support wildcard redirect URLs, +meaning that you have to register all redirect URIs in your Idura Application via the Dashboard. ### Response Type diff --git a/src/snippets/generate-client-secret.mdx b/src/snippets/generate-client-secret.mdx new file mode 100644 index 00000000..3b4b63b4 --- /dev/null +++ b/src/snippets/generate-client-secret.mdx @@ -0,0 +1,24 @@ + + **Client secrets are for [server-side + applications](/verify/reference/glossary/#confidential-client) only.** If you are building a + Single Page Application or a native mobile app, you cannot securely store a secret. Skip this step + and use **[PKCE](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)** instead. + + +1. Go to the **OpenID Connect** section of your Application settings. +2. Toggle on **Enable OAuth2 Code Flow** and click **Save**. + ![Enable OAuth2 Code Flow toggle](./images/oauth2-enable.png) +3. Copy and save the generated **Client Secret**. _Idura only stores the secret as a hashed value, meaning that once you navigate away from this page, + you won't be able to retrieve the raw value again. If you lose your client secret, you will have to generate a new one and update your code._ + ![OAuth2 client secret](./images/oauth2-client-secret.png) + + + +For maximum security in production, we recommend moving away from client secret authentication and replacing it with safer alternatives: + +- **[Private key JWT authentication](/verify/guides/privatekey-jwt/)**: A secure authentication method for traditional web applications based on asymmetric key cryptography. +- **[PKCE (Proof Key for Code Exchange)](/verify/how-it-works/oidc-intro/#authenticate-with-pkce)**: An extension to the Authorization Code flow that eliminates the need for a client secret entirely. + +Learn more in our **[OpenID Connect best security practices](/verify/how-it-works/best-security-practices/)** guide. + + diff --git a/src/snippets/images/oauth2-client-secret.png b/src/snippets/images/oauth2-client-secret.png index 6cba8b52..4ce9c04b 100644 Binary files a/src/snippets/images/oauth2-client-secret.png and b/src/snippets/images/oauth2-client-secret.png differ