Skip to main content
Version: 3.x

OpenID Connect (OIDC)

Key Concepts

The OpenID Connect plugin allows you to integrate with your OAuth provider. This will allow you to move the authentication process to an external provider.

Saleor will require the scopes:

  • openid
  • profile
  • email
  • offline_access - optionally, when you enable refreshing the token
  • saleor:permission - optionally when you enable mapping OAuth permissions to Saleor

Type of integration

The OIDC plugin supports two ways of integration:

  • Saleor as a client for authorization server - Saleor follows Authorization Code Flow to authenticate the user.
  • Saleor as a resource server - requests are authenticated with OAuth access token provided in Authorization header.

Saleor as a client for authorization server

Configuration

To use this flow you, need to configure the plugin by providing values for JSON Web Key Set URL, OAuth Token URL and OAuth Authorization URL on the Saleor Dashboard.

Generating authentication URL

Workflow

Executing externalAuthenticationUrl mutation will prepare special URL which will redirect user to requested page after successfull authentication. After redirection state and code fields will be added to the URL. externalObtainAccessTokens will require both.

Mutation

The mutation takes the following input fields:

  • pluginId: the ID of the authentication plugin
  • input JSONString
    • redirectUrl: the URL where the user should be redirected after successful authentication
mutation ($input: JSONString!) {
externalAuthenticationUrl(
pluginId:"mirumee.authentication.openidconnect",
input: $input
){
authenticationData
accountErrors{
field
message
}
}
}

Query variables:

{
"input": "{\"redirectUri\":\"http://127.0.0.1:3001/callback\"}"
}

Successful response:

{
"data": {
"externalAuthenticationUrl": {
"authenticationData": "{\"authorizationUrl\": \"https://saleor-test.eu.auth0.com/authorize?response_type=code&client_id=RUgv72Cvzd5xjlMtgOEQLJ8QF4eQ3e1U&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Fcallback&scope=openid+profile+email+offline_access&state=eyJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMC9jYWxsYmFjayJ9%3A1l1W9H%3AFsxnhejCQKB4JdFL-t0BqNPrHtODh9T0mG2E3KzT-bQ\"}",
"accountErrors": []
}
}
}

Obtaining access token

Workflow

Mutation

The externalObtainAccessTokens mutation will generate requested access tokens. The mutation takes the following input fields:

  • pluginId: the ID of the authentication plugin
  • input: JSONString
    • code: the authorization code received from the OAuth provider
    • state: the state value received from the OAuth provider
mutation ($input: JSONString!) {
externalObtainAccessTokens(
pluginId:"mirumee.authentication.openidconnect",
input: $input
){
token
refreshToken
csrfToken
user{
id
email
}
accountErrors{
field
code
message
}
}
}

Query variables:

{
"input": "{\"code\": \"uLBlqQwnmKTIDLJ3\", \"state\": \"eyJyZWRpcmVjdFVyaSI6Imh0dHA6Ly8xMjcuMC4wLjE6MzAwMC9jYWxsYmFjayJ9:1l1lXU:93CE6SScisZNX4T93_7VM-JGlUDZa_EflH4RSUAtc-E\"}"
}

Successful response:

{
"data": {
"externalObtainAccessTokens": {
"token": "eyJ0eXAiOiJKV1QiL....SzVVNO6oTVMCTbpgFhqo-yRzsq0Q5ZK2GVn3R_KTjmc",
"refreshToken": "eyJ0eXAiOiJKV1QiLCJ...bi5vcGVuaWRjb25uZWN0In0.o_ZDrQYOImCg1ne7pJKdKB-DNyuW6OKkjNwP05lyPNw",
"csrfToken": "qRLs15tbipqOfZuFs8kQYzpj927vfhBPqWj4jg0Uc9D1WPPpUbw2jEP1R7p7gVL4",
"user": {
"id": "VXNlcjoyNA==",
"email": "saleor.user@saleor.io"
},
"accountErrors": []
}
}
}

Refreshing token

Workflow

¹ refresh token can also be passed as a cookie named refreshToken

Mutation

The externalRefresh mutation will generate new access tokens when provided with a valid refresh token. If the refresh token is not provided as an argument, the plugin will try to read it from a cookie set by the tokenCreate mutation. In that case, a matching CSRF token is required.

The mutation takes the following input fields:

  • pluginId: the ID of the authentication plugin
  • input: JSONString
    • refreshToken: the refresh token which should be used to refresh the access tokens
    • csrfToken: required when refreshToken is not provided as an input
mutation ($input: JSONString!) {
externalRefresh(
pluginId:"mirumee.authentication.openidconnect",
input: $input
){
token
refreshToken
csrfToken
accountErrors{
field
message
code
}
}
}

Query variables:

{
"input": "{\"refreshToken\": \"ABCDE\"}"
}

Successful response:

{
"data": {
"externalRefresh": {
"token": "eyJ0eXAiOiJKV1QiLCJhbGci....-pk-qCvbJ1M7tqSzP0",
"refreshToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIU...sBboyMFcWTIe92NcWlqEI9AYlJL6o",
"csrfToken": "Ejdvo8PTLG0M9YAGHCnBvyldmDrd6SjmhfQDWBIaCymZzW8eRUAL4sz4Cx91q0yR",
"accountErrors": []
}
}
}

Token verification

Mutation

To verify the token, use the following externalVerify mutation.

The mutation takes the following input fields:

  • pluginId: the ID of the authentication plugin
  • input: JSONString
    • refreshToken: the refresh token which should be used to refresh the access token
    • csrfToken: required when refreshToken is not provided as an input
mutation ($input: JSONString!) {
externalVerify(
pluginId:"mirumee.authentication.openidconnect",
input: $input
){
isValid
verifyData
user{
userPermissions{
code
name
}
}
}
}

Query variables:

{
"input": "{\"token\": \"eyJ0eXAiOiJK...J1M7tqSzP0\"}"
}

Successful response:

{
"data": {
"externalVerify": {
"isValid": true,
"verifyData": "{\"iat\": 1602143144, \"token\": \"xgS4ZELKlUHQ\", \"email\": \"admin@example.com\", \"type\": \"access\", \"user_id\": \"VXNlcjoyNQ==\", \"is_staff\": false, \"exp\": 1602179144, \"oauth_access_key\": \"tM-LHXMbxP5IANhPUd24_y5jjv0SCSj2\", \"owner\": \"mirumee.authentication.openidconnect\"}",
"user": {
"email": "admin@example.com",
"userPermissions": []
},
"accountErrors": []
}
}
}

Workflow

Logout

Workflow

You can prepare the logout URL by calling externalLogout mutation. All values passed in field input will be added as GET parameters to the logout request.

  • pluginId: the ID of the authentication plugin
  • input: JSONString
    • returnTo: the URL where a user should be redirected

Mutation

mutation ($input: JSONString!) {
externalLogout(
pluginId:"mirumee.authentication.openidconnect",
input: $input
){
logoutData
accountErrors{
field
message
code
}
}
}

Query variables:

{
"input": "{\"returnTo\": \"http://localhost:3001\"}"
}

Successful response:

{
"data": {
"externalLogout": {
"logoutData": "{\"logoutUrl\": \"https://saleor-test.eu.auth0.com/v2/logout?returnTo=http%3A%2F%2Flocalhost%3A3000\"}",
"accountErrors": []
}
}
}

Saleor as a resource server

In resource server flow, Saleor API only verifies if the token included in the request is valid. Operations like login, logout or token refresh have to be handled directly by auth provider API.

The authorization header has the following format:

Authorization: Bearer <your-OAuth-access-token>

Configuration

To use this flow you need to provide values for JSON Web Key Set URL and User info URL on the Saleor Dashboard side.

Access token permissions

When OAuth permissions are enabled, Saleor will try to fetch own's permissions from access_token.scope. In case when token's scope doesn't have any Saleor's permissions, it will try to find permissions in access_token.permissions.

User authentication flow

OAuth permissions

Saleor can use OAuth permissions assigned to a user. It maps internal permissions to OAuth scopes and attaches it to the authorization request.

OAuth permission scopes

OAuth scope nameSaleor NameDescription
saleor:manage_appsMANAGE_APPSManage apps
saleor:manage_channelsMANAGE_CHANNELSManage Saleor's channels
saleor:manage_checkoutsMANAGE_CHECKOUTSManage checkout
saleor:manage_discountsMANAGE_DISCOUNTSManage discounts
saleor:manage_gift_cardMANAGE_GIFT_CARDManage gift cards
saleor:manage_menusMANAGE_MENUSManage the structure of menus
saleor:manage_ordersMANAGE_ORDERSAccess to orders data
saleor:manage_pagesMANAGE_PAGESManage pages
saleor:manage_page_types_and_attributesMANAGE_PAGE_TYPES_AND_ATTRIBUTESManage page types and attributes
saleor:manage_pluginsMANAGE_PLUGINSManage plugins
saleor:manage_productsMANAGE_PRODUCTSManage products
saleor:manage_product_types_and_attributesMANAGE_PRODUCT_TYPES_AND_ATTRIBUTESManage products and attributes
saleor:manage_settingsMANAGE_SETTINGSManage shop settings
saleor:manage_shippingMANAGE_SHIPPINGManage shipping
saleor:manage_staffMANAGE_STAFFAccess to staff users data
saleor:manage_translationsMANAGE_TRANSLATIONSManage tranlsations
saleor:manage_usersMANAGE_USERSAccess to customers data
saleor:staff-User is marked as a staff user

If Use OAuth scope permissions is enabled, any permissions granted to a user on the authentication provider side will be used as the effective permissions on the Saleor side. Please see the documentation of your authentication server to see how to manage permissions and how to configure role-based access control (RBAC).

note

Before enabling this feature, make sure that your OAuth provider has enabled role-based access control (RBAC).

External links