CINXE.COM

Securing APIs - Authentication and Authorization Service

<!doctype html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="icon" href="../../../assets/images/favicon.png"> <meta name="generator" content="mkdocs-1.3.1, mkdocs-material-8.5.3"> <title>Securing APIs - Authentication and Authorization Service</title> <link rel="stylesheet" href="../../../assets/stylesheets/main.7a952b86.min.css"> <link rel="stylesheet" href="../../../assets/stylesheets/palette.cbb835fc.min.css"> <link rel="stylesheet" href="../../../stylesheets/fonts.css"> <link rel="stylesheet" href="../../../stylesheets/kuri-kuri.css"> <script>__md_scope=new URL("../../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script> </head> <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none"> <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off"> <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off"> <label class="md-overlay" for="__drawer"></label> <div data-md-component="skip"> <a href="#securing-apis" class="md-skip"> Skip to content </a> </div> <div data-md-component="announce"> </div> <header class="md-header" data-md-component="header"> <nav class="md-header__inner md-grid" aria-label="Header"> <a href="../../.." title="Authentication and Authorization Service" class="md-header__button md-logo" aria-label="Authentication and Authorization Service" data-md-component="logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg> </a> <label class="md-header__button md-icon" for="__drawer"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg> </label> <div class="md-header__title" data-md-component="header-title"> <div class="md-header__ellipsis"> <div class="md-header__topic"> <span class="md-ellipsis"> Authentication and Authorization Service </span> </div> <div class="md-header__topic" data-md-component="header-topic"> <span class="md-ellipsis"> Securing APIs </span> </div> </div> </div> <label class="md-header__button md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg> </label> <div class="md-search" data-md-component="search" role="dialog"> <label class="md-search__overlay" for="__search"></label> <div class="md-search__inner" role="search"> <form class="md-search__form" name="search"> <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required> <label class="md-search__icon md-icon" for="__search"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg> </label> <nav class="md-search__options" aria-label="Search"> <button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg> </button> </nav> </form> <div class="md-search__output"> <div class="md-search__scrollwrap" data-md-scrollfix> <div class="md-search-result" data-md-component="search-result"> <div class="md-search-result__meta"> Initializing search </div> <ol class="md-search-result__list"></ol> </div> </div> </div> </div> </div> <div class="md-header__source"> <a href="https://gitlab.cern.ch/authzsvc/docs/authzsvc-docs" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg> </div> <div class="md-source__repository"> authzsvc-docs </div> </a> </div> </nav> </header> <div class="md-container" data-md-component="container"> <main class="md-main" data-md-component="main"> <div class="md-main__inner md-grid"> <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0"> <label class="md-nav__title" for="__drawer"> <a href="../../.." title="Authentication and Authorization Service" class="md-nav__button md-logo" aria-label="Authentication and Authorization Service" data-md-component="logo"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54Z"/></svg> </a> Authentication and Authorization Service </label> <div class="md-nav__source"> <a href="https://gitlab.cern.ch/authzsvc/docs/authzsvc-docs" title="Go to repository" class="md-source" data-md-component="source"> <div class="md-source__icon md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg> </div> <div class="md-source__repository"> authzsvc-docs </div> </a> </div> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../.." class="md-nav__link"> CERN Authentication and Authorization Services </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2" type="checkbox" id="__nav_2" > <label class="md-nav__link" for="__nav_2"> User authentication <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="User authentication" data-md-level="1"> <label class="md-nav__title" for="__nav_2"> <span class="md-nav__icon md-icon"></span> User authentication </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../authentication-options/" class="md-nav__link"> Authentication options </a> </li> <li class="md-nav__item"> <a href="../../two-factor-authentication/" class="md-nav__link"> Two factor authentication </a> </li> <li class="md-nav__item"> <a href="../../kerberos-authentication/" class="md-nav__link"> Kerberos </a> </li> <li class="md-nav__item"> <a href="../../time-limits/" class="md-nav__link"> Time limits </a> </li> <li class="md-nav__item"> <a href="../../autologon/" class="md-nav__link"> Autologon </a> </li> <li class="md-nav__item"> <a href="../../account-lifecycle/" class="md-nav__link"> Account Lifecycle </a> </li> <li class="md-nav__item"> <a href="../../unconfirmed-identities/" class="md-nav__link"> Unconfirmed identities </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" checked> <label class="md-nav__link" for="__nav_3"> Securing applications <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Securing applications" data-md-level="1"> <label class="md-nav__title" for="__nav_3"> <span class="md-nav__icon md-icon"></span> Securing applications </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../applications/application-configuration/" class="md-nav__link"> Configuring your application </a> </li> <li class="md-nav__item"> <a href="../../../applications/adding-application/" class="md-nav__link"> Adding your application to the service </a> </li> <li class="md-nav__item"> <a href="../../../applications/permission-scheme/" class="md-nav__link"> Defining the permissions scheme </a> </li> <li class="md-nav__item"> <a href="../../../applications/role-based-permissions/" class="md-nav__link"> Role based permissions (recommended) </a> </li> <li class="md-nav__item"> <a href="../../../applications/group-based-permissions/" class="md-nav__link"> Group based permissions </a> </li> <li class="md-nav__item"> <a href="../../../applications/sso-registration/" class="md-nav__link"> Registering your application to SSO </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_7" type="checkbox" id="__nav_3_7" > <label class="md-nav__link" for="__nav_3_7"> SAML <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="SAML" data-md-level="2"> <label class="md-nav__title" for="__nav_3_7"> <span class="md-nav__icon md-icon"></span> SAML </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../saml/saml/" class="md-nav__link"> About </a> </li> <li class="md-nav__item"> <a href="../../saml/config/" class="md-nav__link"> Configuration </a> </li> <li class="md-nav__item"> <a href="../../saml/shibboleth-integration/" class="md-nav__link"> Shibboleth integration </a> </li> <li class="md-nav__item"> <a href="../../saml/shibboleth-migration/" class="md-nav__link"> Shibboleth migration from the old SSO </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--active md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3_8" type="checkbox" id="__nav_3_8" checked> <label class="md-nav__link" for="__nav_3_8"> OIDC <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="OIDC" data-md-level="2"> <label class="md-nav__title" for="__nav_3_8"> <span class="md-nav__icon md-icon"></span> OIDC </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../oidc/" class="md-nav__link"> About </a> </li> <li class="md-nav__item"> <a href="../token-requests/" class="md-nav__link"> Token Requests </a> </li> <li class="md-nav__item"> <a href="../scopes/" class="md-nav__link"> Scopes </a> </li> <li class="md-nav__item"> <a href="../config/" class="md-nav__link"> OIDC configuration and usage </a> </li> <li class="md-nav__item"> <a href="../apache/" class="md-nav__link"> Apache configuration </a> </li> <li class="md-nav__item md-nav__item--active"> <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc"> <label class="md-nav__link md-nav__link--active" for="__toc"> Securing APIs <span class="md-nav__icon md-icon"></span> </label> <a href="./" class="md-nav__link md-nav__link--active"> Securing APIs </a> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#general-recommendations" class="md-nav__link"> General recommendations </a> </li> <li class="md-nav__item"> <a href="#server-configuration-with-cernsso_apache" class="md-nav__link"> Server configuration with cernsso_apache </a> <nav class="md-nav" aria-label="Server configuration with cernsso_apache"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#directory-server" class="md-nav__link"> Directory server </a> </li> <li class="md-nav__item"> <a href="#proxy-server" class="md-nav__link"> Proxy server </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#registering-your-application" class="md-nav__link"> Registering your application </a> </li> <li class="md-nav__item"> <a href="#client-configuration" class="md-nav__link"> Client configuration </a> <nav class="md-nav" aria-label="Client configuration"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#automatic-access" class="md-nav__link"> Automatic access </a> </li> <li class="md-nav__item"> <a href="#interactive-access-from-any-terminal" class="md-nav__link"> Interactive access from any terminal </a> </li> <li class="md-nav__item"> <a href="#interactive-access-with-locally-managed-tokens" class="md-nav__link"> Interactive access with locally managed tokens </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#cookies-and-other-alternatives" class="md-nav__link"> Cookies and other alternatives </a> </li> <li class="md-nav__item"> <a href="#kerberos" class="md-nav__link"> Kerberos </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../api-access/" class="md-nav__link"> API Access </a> </li> <li class="md-nav__item"> <a href="../exchange-for-api/" class="md-nav__link"> Token Exchange </a> </li> <li class="md-nav__item"> <a href="../device-code/" class="md-nav__link"> Device Code </a> </li> <li class="md-nav__item"> <a href="../libraries/" class="md-nav__link"> Suggested libraries </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../../applications/examples/" class="md-nav__link"> Examples </a> </li> <li class="md-nav__item"> <a href="../../../applications/qa-environment/" class="md-nav__link"> QA Environment </a> </li> <li class="md-nav__item"> <a href="../../../applications/command-line-tools/" class="md-nav__link"> Command line tools </a> </li> <li class="md-nav__item"> <a href="../../faqs/" class="md-nav__link"> FAQs </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4" type="checkbox" id="__nav_4" > <label class="md-nav__link" for="__nav_4"> Group Management System <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Group Management System" data-md-level="1"> <label class="md-nav__title" for="__nav_4"> <span class="md-nav__icon md-icon"></span> Group Management System </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../roadmap/group-missing-features/" class="md-nav__link"> Missing features </a> </li> <li class="md-nav__item"> <a href="../../../groups/special-groups/" class="md-nav__link"> Special groups </a> </li> <li class="md-nav__item"> <a href="../../../groups/dynamic-guidance/" class="md-nav__link"> Dynamic groups </a> </li> <li class="md-nav__item"> <a href="../../../groups/csv/" class="md-nav__link"> CSV </a> </li> <li class="md-nav__item"> <a href="../../../groups/e-groups-to-gms-sync-scenario/" class="md-nav__link"> E-Groups to GMS transition </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" > <label class="md-nav__link" for="__nav_5"> Resources lifecycle and eligibility <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Resources lifecycle and eligibility" data-md-level="1"> <label class="md-nav__title" for="__nav_5"> <span class="md-nav__icon md-icon"></span> Resources lifecycle and eligibility </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../resources/resources/" class="md-nav__link"> Introduction </a> </li> <li class="md-nav__item"> <a href="../../../resources/resource-lifecycle-integration/" class="md-nav__link"> Integration </a> </li> <li class="md-nav__item"> <a href="../../../resources/resource-states/" class="md-nav__link"> Resource States </a> </li> <li class="md-nav__item"> <a href="../../../resources/push-rest-api/" class="md-nav__link"> Resources REST API (push) </a> </li> <li class="md-nav__item"> <a href="../../../resources/policies/" class="md-nav__link"> Custom Resource Policies </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" > <label class="md-nav__link" for="__nav_6"> Documents <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Documents" data-md-level="1"> <label class="md-nav__title" for="__nav_6"> <span class="md-nav__icon md-icon"></span> Documents </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../documents/why-keycloak/" class="md-nav__link"> Why Keycloak </a> </li> <li class="md-nav__item"> <a href="../../../documents/presentations/" class="md-nav__link"> Presentations </a> </li> <li class="md-nav__item"> <a href="../../../documents/our-contributions/" class="md-nav__link"> Our contributions to Keycloak </a> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" > <label class="md-nav__link" for="__nav_7"> Services <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Services" data-md-level="1"> <label class="md-nav__title" for="__nav_7"> <span class="md-nav__icon md-icon"></span> Services </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../services/" class="md-nav__link"> Overview </a> </li> <li class="md-nav__item"> <a href="../../../services/instances/" class="md-nav__link"> Links to instances </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_3" type="checkbox" id="__nav_7_3" > <label class="md-nav__link" for="__nav_7_3"> Authorization Service API <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Authorization Service API" data-md-level="2"> <label class="md-nav__title" for="__nav_7_3"> <span class="md-nav__icon md-icon"></span> Authorization Service API </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../authzsvc/overview/" class="md-nav__link"> Overview </a> </li> <li class="md-nav__item"> <a href="../../../authzsvc/managed-applications/" class="md-nav__link"> Managing applications for other users </a> </li> <li class="md-nav__item"> <a href="../../../authzsvc/roles/" class="md-nav__link"> Role definitions </a> </li> <li class="md-nav__item"> <a href="../../../authzsvc/model/" class="md-nav__link"> Model (attributes) </a> </li> <li class="md-nav__item"> <a href="../../../authzsvc/examples/" class="md-nav__link"> Examples </a> </li> </ul> </nav> </li> </ul> </nav> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_8" type="checkbox" id="__nav_8" > <label class="md-nav__link" for="__nav_8"> Help <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Help" data-md-level="1"> <label class="md-nav__title" for="__nav_8"> <span class="md-nav__icon md-icon"></span> Help </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../trouble-shooting/edugain-authentication/" class="md-nav__link"> eduGAIN Authentication </a> </li> <li class="md-nav__item"> <a href="../../../trouble-shooting/2fa-tips/" class="md-nav__link"> 2FA Tips </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../../privacy-notice/" class="md-nav__link"> Privacy notice </a> </li> <li class="md-nav__item md-nav__item--nested"> <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_10" type="checkbox" id="__nav_10" > <label class="md-nav__link" for="__nav_10"> Migration notes <span class="md-nav__icon md-icon"></span> </label> <nav class="md-nav" aria-label="Migration notes" data-md-level="1"> <label class="md-nav__title" for="__nav_10"> <span class="md-nav__icon md-icon"></span> Migration notes </label> <ul class="md-nav__list" data-md-scrollfix> <li class="md-nav__item"> <a href="../../../migrations/keycloak24/" class="md-nav__link"> Keycloak 24 </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="../../../contact/" class="md-nav__link"> Contact </a> </li> </ul> </nav> </div> </div> </div> <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" > <div class="md-sidebar__scrollwrap"> <div class="md-sidebar__inner"> <nav class="md-nav md-nav--secondary" aria-label="Table of contents"> <label class="md-nav__title" for="__toc"> <span class="md-nav__icon md-icon"></span> Table of contents </label> <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix> <li class="md-nav__item"> <a href="#general-recommendations" class="md-nav__link"> General recommendations </a> </li> <li class="md-nav__item"> <a href="#server-configuration-with-cernsso_apache" class="md-nav__link"> Server configuration with cernsso_apache </a> <nav class="md-nav" aria-label="Server configuration with cernsso_apache"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#directory-server" class="md-nav__link"> Directory server </a> </li> <li class="md-nav__item"> <a href="#proxy-server" class="md-nav__link"> Proxy server </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#registering-your-application" class="md-nav__link"> Registering your application </a> </li> <li class="md-nav__item"> <a href="#client-configuration" class="md-nav__link"> Client configuration </a> <nav class="md-nav" aria-label="Client configuration"> <ul class="md-nav__list"> <li class="md-nav__item"> <a href="#automatic-access" class="md-nav__link"> Automatic access </a> </li> <li class="md-nav__item"> <a href="#interactive-access-from-any-terminal" class="md-nav__link"> Interactive access from any terminal </a> </li> <li class="md-nav__item"> <a href="#interactive-access-with-locally-managed-tokens" class="md-nav__link"> Interactive access with locally managed tokens </a> </li> </ul> </nav> </li> <li class="md-nav__item"> <a href="#cookies-and-other-alternatives" class="md-nav__link"> Cookies and other alternatives </a> </li> <li class="md-nav__item"> <a href="#kerberos" class="md-nav__link"> Kerberos </a> </li> </ul> </nav> </div> </div> </div> <div class="md-content" data-md-component="content"> <article class="md-content__inner md-typeset"> <a href="https://gitlab.cern.ch/authzsvc/docs/authzsvc-docs/-/blob/master/docs/user-documentation/oidc/securing-apis.md" title="Edit this page" class="md-content__button md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25Z"/></svg> </a> <h1 id="securing-apis">Securing APIs</h1> <p>You can protect and integrate a web API with the CERN Single Sign-On by configuring it as an <a href="https://www.oauth.com/oauth2-servers/the-resource-server/">OAuth2 Resource Server</a>. This is a widely used standard and you will find trusted libraries that support it for almost any programming language.</p> <h2 id="general-recommendations">General recommendations</h2> <p>In order to make a secure integration with the CERN SSO make sure to follow these recommendations:</p> <ol> <li>Verify the token signatures: most libraries will require you to do that, you will find the public keys for your configuration in the following URL: <code>https://auth.cern.ch/auth/realms/cern/protocol/openid-connect/certs</code></li> <li>Validate the audience (<code>aud</code>) of bearer tokens: it must match your Client ID. If you skip this step, you will be accepting any valid token for any CERN application.</li> <li>Verify the user roles if needed, by checking the <code>cern_roles</code> token claim.</li> </ol> <h2 id="server-configuration-with-cernsso_apache">Server configuration with cernsso_apache</h2> <p>Our Puppet module <a href="https://gitlab.cern.ch/ai/it-puppet-module-cernsso_apache">cernsso_apache</a> can configure an Apache web server as an OAuth2 Resource Server. If you are using Apache to expose an API or any web service that needs to be accessed programmatically, this will allow other services to authenticate to your service by following web standards and using trusted libraries. Our module will include all the specific configuration for the CERN SSO automatically, including the recommendations from above.</p> <p>Here are some configuration examples:</p> <h3 id="directory-server">Directory server</h3> <p>Use this configuration for protecting files or CGI scripts.</p> <div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s">&#39;cernsso_apache&#39;</span><span class="p">:</span> <span class="w"> </span><span class="na">client_id</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;my-website&#39;</span><span class="p">,</span><span class="w"> </span><span class="c"># Your Client ID, as in the Application Portal</span> <span class="w"> </span><span class="na">server_type</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;directory&#39;</span><span class="p">,</span> <span class="w"> </span><span class="na">document_root</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;/var/www/my-website&#39;</span> <span class="w"> </span><span class="na">required_role</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;default-role&#39;</span><span class="p">,</span> <span class="w"> </span><span class="na">enable_relying_party</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">false</span><span class="p">,</span> <span class="w"> </span><span class="na">enable_resource_server</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">true</span><span class="p">,</span> <span class="w"> </span><span class="na">resource_server_paths</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">[</span><span class="s">&#39;/&#39;</span><span class="p">],</span> <span class="p">}</span> </code></pre></div> <p>You can read session information in your scripts from the HTTP headers set by the Apache proxy, you will find more information about that in the <a href="https://gitlab.cern.ch/ai/it-puppet-module-cernsso_apache/-/blob/qa/code/README.md#authentication-headers">module documentation</a>.</p> <h3 id="proxy-server">Proxy server</h3> <p>Use this configuration to configure Apache as a reverse proxy for a locally running API. The API can be treated as a black box, and our module will configure authentication and authorisation for it. You can also read session information in the API from the HTTP headers sent by the Apache proxy, you will find more information about that in the <a href="https://gitlab.cern.ch/ai/it-puppet-module-cernsso_apache/-/blob/qa/code/README.md#authentication-headers">module documentation</a>.</p> <div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s">&#39;cernsso_apache&#39;</span><span class="p">:</span> <span class="w"> </span><span class="na">client_id</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;my-website&#39;</span><span class="p">,</span><span class="w"> </span><span class="c"># Your Client ID, as in the Application Portal</span> <span class="w"> </span><span class="na">required_role</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="s">&#39;default-role&#39;</span><span class="p">,</span> <span class="w"> </span><span class="na">localapp_port</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="mi">3000</span><span class="p">,</span> <span class="w"> </span><span class="na">enable_relying_party</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">false</span><span class="p">,</span> <span class="w"> </span><span class="na">enable_resource_server</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">true</span><span class="p">,</span> <span class="w"> </span><span class="na">resource_server_paths</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">[</span><span class="s">&#39;/&#39;</span><span class="p">],</span> <span class="p">}</span> </code></pre></div> <h2 id="registering-your-application">Registering your application</h2> <p>Register your API as an OpenID-Connect (OIDC) client <a href="../../../applications/sso-registration/">here</a>. Depending on who will use it it can be a public or a confidential client.</p> <ul> <li>Public client: Since there are no client secrets, you can use an already registered public client (Client ID: <code>public-client</code>), but you won't be able to manage user roles in this case. All CERN and eduGAIN users will be able to get tokens for this client. If you have to define your own set of allowed users, register your public client and define user roles in the <a href="https://application-portal.web.cern.ch">Application Portal</a>.</li> <li>Confidential client: You will need to store a Client Secret in every client accessing the API, and use it to get a valid token.</li> </ul> <p>When selecting the option "My application cannot store a client secret safely" your client will be public, otherwise it will be a confidential client.</p> <h2 id="client-configuration">Client configuration</h2> <p>APIs can be accessed by services (automatically) or by users (interactively). We provide different tools for each use case.</p> <h3 id="automatic-access">Automatic access</h3> <ul> <li> <p>If you registered your server application as a <strong>confidential</strong> client (i.e. you have a Client ID and a Client Secret), you can get tokens using the standard <a href="https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/">OAuth2 Client Credentials Grant</a> or the CERN <a href="../api-access/">API Access endpoint</a> with the same Client ID and Secret. You have to tick the box "My application will need to get tokens using its own Client ID and Secret" in the application registration.</p> </li> <li> <p>In other cases, you or your user will have to use any client that has been registered by ticking the box "My application will need to get tokens using its own Client ID and Secret" (e.g. <code>public-client</code>). Then use the CERN <a href="../api-access/">API Access endpoint</a>.</p> </li> </ul> <h3 id="interactive-access-from-any-terminal">Interactive access from any terminal</h3> <div class="admonition info"> <p class="admonition-title">Info</p> <p>If you get the following error: <code>Client is not allowed to initiate OAuth 2.0 Device Authorization Grant. The flow is disabled for the client.</code> please open a support ticket and we will fix your client.</p> </div> <p>Register your application as a <strong>public</strong> client or use the already registered <code>public-client</code> by accepting it as a valid audience. Then any user will be able to get access using OAuth2 Device Authorization Grant or <code>auth-get-user-token</code> (this command is available in the package <code>auth-get-sso-cookie</code>). You can see how it works in the following example.</p> <div class="highlight"><pre><span></span><code>auth-get-user-token<span class="w"> </span>-c<span class="w"> </span>public-client<span class="w"> </span>-o<span class="w"> </span>token.txt<span class="w"> </span>-x <span class="nv">token</span><span class="o">=</span><span class="k">$(</span>&lt;token.txt<span class="k">)</span> curl<span class="w"> </span>-X<span class="w"> </span>PUT<span class="w"> </span><span class="s2">&quot;https://myapi.cern.ch/api/foobar&quot;</span><span class="w"> </span>-H<span class="w"> </span><span class="s2">&quot;authorization: Bearer </span><span class="nv">$token</span><span class="s2">&quot;</span><span class="w"> </span>-d<span class="w"> </span><span class="s2">&quot;{\&quot;foo\&quot;: \&quot;bar\&quot;}&quot;</span> </code></pre></div> <p>If you run this in a bash script, the user will see something like the following output:</p> <div class="highlight"><pre><span></span><code>User code: HCTK-VTVK Please open the following link in your web browser: https://auth.cern.ch/auth/realms/cern/device?user_code=HCTK-VTVK Sign in using the link above and press enter to continue </code></pre></div> <p>They will be able to log in using the link in the terminal output and following the instructions to get a valid token for your API. Usually they can open the link in their main browser session, so they don't have to input their credentials again if they are already logged in.</p> <h3 id="interactive-access-with-locally-managed-tokens">Interactive access with locally managed tokens</h3> <p>The CERN SSO is compatible with <a href="https://github.com/indigo-dc/oidc-agent">oidc-agent</a>, which is "a set of tools to manage OpenID Connect tokens and make them easily usable from the command line". This tool is already installed in LXPLUS and AIADM instances. It's a general purpose tool with many options that you can explore to adapt it to your use case, but if you only need it to get access tokens here is a quick recipe that you can use:</p> <div class="highlight"><pre><span></span><code>oidc-gen<span class="w"> </span>--pub<span class="w"> </span>--client-id<span class="w"> </span>oidc-agent<span class="w"> </span>--client-secret<span class="w"> </span><span class="s2">&quot;&quot;</span><span class="w"> </span>--redirect-uri<span class="w"> </span>http://localhost:43985<span class="w"> </span>--issuer<span class="w"> </span>https://auth.cern.ch/auth/realms/cern<span class="w"> </span>--scope<span class="w"> </span><span class="s2">&quot;openid offline_access&quot;</span><span class="w"> </span>cernsso </code></pre></div> <p>This command causes the tool <code>oidc-agent</code> to request a token from CERN SSO for the client called <code>oidc-agent</code> (which is already configured in CERN SSO as a public client). It will prompt you to launch a browser and complete the authentication before returning an OIDC token (with audience set to <code>oidc-agent</code>). Then you will be prompted for an encryption password. This password will be used to encrypt and store locally the OIDC refresh token. Once the setup is complete, you will be able to get a valid access token by running:</p> <div class="highlight"><pre><span></span><code>oidc-token<span class="w"> </span>cernsso </code></pre></div> <h2 id="cookies-and-other-alternatives">Cookies and other alternatives</h2> <p>Cookies or other authentication protocols (e.g. SAML) are not a supported authentication mechanism for APIs when used together with the CERN Single Sign-On. We are aware that many older services used this, and their client integration was officially supported with the <code>cern-get-sso-cookie</code> tool. Clients for these tools can migrate to <code>auth-get-sso-cookie</code>, but this authentication flow will not be supported for newly developed APIs.</p> <h2 id="kerberos">Kerberos</h2> <p>Kerberos is supported for the context of interactive access, with OAuth2 Device Authorization Grant or <code>auth-get-user-token</code> when a user logs in using a web browser window.</p> <p>We don't support the development of automatic integrations (e.g. cron jobs) that exchange Kerberos sessions with Single Sign-On tokens.</p> </article> </div> </div> </main> <footer class="md-footer"> <nav class="md-footer__inner md-grid" aria-label="Footer" > <a href="../apache/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Apache configuration" rel="prev"> <div class="md-footer__button md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg> </div> <div class="md-footer__title"> <div class="md-ellipsis"> <span class="md-footer__direction"> Previous </span> Apache configuration </div> </div> </a> <a href="../api-access/" class="md-footer__link md-footer__link--next" aria-label="Next: API Access" rel="next"> <div class="md-footer__title"> <div class="md-ellipsis"> <span class="md-footer__direction"> Next </span> API Access </div> </div> <div class="md-footer__button md-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4Z"/></svg> </div> </a> </nav> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class="md-copyright"> Made with <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener"> Material for MkDocs </a> </div> </div> </div> </footer> </div> <div class="md-dialog" data-md-component="dialog"> <div class="md-dialog__inner md-typeset"></div> </div> <script id="__config" type="application/json">{"base": "../../..", "features": [], "search": "../../../assets/javascripts/workers/search.5bf1dace.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version.title": "Select version"}}</script> <script src="../../../assets/javascripts/bundle.37e9125f.min.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10