Pass Parameters to Identity Providers
You can pass provider-specific parameters to an Identity Provider during authentication. The values can either be static per connection or dynamic per user. Note the following restrictions:
Only valid OAuth 2.0/OIDC parameters are accepted.
Not all Identity Providers support upstream parameters. Check with the specific Identity Provider before you proceed with your implementation.
SAML identity providers, in particular, do not support upstream parameters.
Static parameters
You can configure static parameters per connection with the Connections endpoints of our Management API. Each time your connection is used, the specified parameters will be sent to the Identity Provider.
When you create or update a connection, use the upstream_params
element of the options
attribute.
Example: WordPress
As an example, let's use WordPress, which allows you to pass an optional blog
parameter to its OAuth 2.0 authorization endpoint (for more information, see WordPress's OAuth 2.0 documentation).
Let's assume that you have a working WordPress connection and you want to always request that users have access to the myblog.wordpress.com
blog when logging in with it. To do this, assign WordPress's blog
parameter a default value of myblog.wordpress.com
.
First, we will use the Get Connection endpoint, to retrieve the existing values of the options
object. This is mandatory since the Update Connection endpoint, which we will use next, overrides this object will be overridden, so if parameters are missing they will be lost after the update.
curl --request GET \
--url 'https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID' \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'content-type: application/json'
Was this helpful?
var client = new RestClient("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer YOUR_ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("authorization", "Bearer YOUR_ACCESS_TOKEN")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.get("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")
.header("authorization", "Bearer YOUR_ACCESS_TOKEN")
.header("content-type", "application/json")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID',
headers: {authorization: 'Bearer YOUR_ACCESS_TOKEN', 'content-type': 'application/json'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN",
@"content-type": @"application/json" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"authorization: Bearer YOUR_ACCESS_TOKEN",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
headers = {
'authorization': "Bearer YOUR_ACCESS_TOKEN",
'content-type': "application/json"
}
conn.request("GET", "/YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer YOUR_ACCESS_TOKEN'
request["content-type"] = 'application/json'
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let headers = [
"authorization": "Bearer YOUR_ACCESS_TOKEN",
"content-type": "application/json"
]
let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Let's say that the options
contents for our WordPress connection are the following:
{
"options": {
"client_id": "",
"profile": true,
"scope": ["profile"]
}
}
Was this helpful?
Now we can send the update request, copying the existing options
contents and adding also the blog
parameter.
curl --request PATCH \
--url 'https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID' \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'content-type: application/json' \
--data '{"options":{"client_id":"","profile":true,"scope":["profile"],"upstream_params":{"blog":{"value":"myblog.wordpress.com"}}}}'
Was this helpful?
var client = new RestClient("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID");
var request = new RestRequest(Method.PATCH);
request.AddHeader("authorization", "Bearer YOUR_ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID"
payload := strings.NewReader("{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("authorization", "Bearer YOUR_ACCESS_TOKEN")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.patch("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")
.header("authorization", "Bearer YOUR_ACCESS_TOKEN")
.header("content-type", "application/json")
.body("{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'PATCH',
url: 'https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID',
headers: {authorization: 'Bearer YOUR_ACCESS_TOKEN', 'content-type': 'application/json'},
data: {
options: {
client_id: '',
profile: true,
scope: ['profile'],
upstream_params: {blog: {value: 'myblog.wordpress.com'}}
}
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN",
@"content-type": @"application/json" };
NSDictionary *parameters = @{ @"options": @{ @"client_id": @"", @"profile": @YES, @"scope": @[ @"profile" ], @"upstream_params": @{ @"blog": @{ @"value": @"myblog.wordpress.com" } } } };
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => "{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}",
CURLOPT_HTTPHEADER => [
"authorization: Bearer YOUR_ACCESS_TOKEN",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
payload = "{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}"
headers = {
'authorization': "Bearer YOUR_ACCESS_TOKEN",
'content-type': "application/json"
}
conn.request("PATCH", "/YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Patch.new(url)
request["authorization"] = 'Bearer YOUR_ACCESS_TOKEN'
request["content-type"] = 'application/json'
request.body = "{\"options\":{\"client_id\":\"\",\"profile\":true,\"scope\":[\"profile\"],\"upstream_params\":{\"blog\":{\"value\":\"myblog.wordpress.com\"}}}}"
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let headers = [
"authorization": "Bearer YOUR_ACCESS_TOKEN",
"content-type": "application/json"
]
let parameters = ["options": [
"client_id": "",
"profile": true,
"scope": ["profile"],
"upstream_params": ["blog": ["value": "myblog.wordpress.com"]]
]] as [String : Any]
let postData = JSONSerialization.data(withJSONObject: parameters, options: [])
let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/connections/YOUR-WORDPRESS-CONNECTION-ID")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Now every time a user authenticates with this connection the request to Wordpress will include the query parameter blog=myblog.wordpress.com
.
Dynamic parameters
You can configure upstream parameters per user. This way when a user authenticates, the parameters will be dynamically added to the authorization query.
To do this, use the upstream_params
element of the options
attribute to specify a mapping between one of the existing accepted parameters to the parameter accepted by the Identity Provider.
Field list
Here are fields available for the enum
parameter:
acr_values
audience
client_id
display
id_token_hint
login_hint
max_age
prompt
resource
response_mode
response_type
ui_locales
Example: Twitter
As an example, let's use Twitter, which allows you to pass an optional screen_name
parameter to its OAuth authorization endpoint (for more information, see Twitter's API reference).
To continue, you should already have a working Twitter connection; to learn how to configure one, see Connect Your App to Twitter.
Twitter's screen_name
parameter pre-fills the username input box of the login screen with the given value, so we want to map it to the existing accepted parameter of login_hint
.
Let's assume that you already retrieved the contents of the options
object (like we did in the previous paragraph) and they are the following:
"options": {
"client_id": "thisismyid",
"client_secret": "thisismysecret",
"profile": true
}
Was this helpful?
Send the update request, copying the existing options
contents and adding also the screen_name
parameter.
curl --request PATCH \
--url 'https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID' \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN' \
--header 'content-type: application/json' \
--data '{"options": {"client_id": "thisismyid", "client_secret": "thisismysecret", "profile": true, "upstream_params": {"screen_name": {"alias": "login_hint"}}}}'
Was this helpful?
var client = new RestClient("https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID");
var request = new RestRequest(Method.PATCH);
request.AddHeader("authorization", "Bearer YOUR_ACCESS_TOKEN");
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID"
payload := strings.NewReader("{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("authorization", "Bearer YOUR_ACCESS_TOKEN")
req.Header.Add("content-type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.patch("https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID")
.header("authorization", "Bearer YOUR_ACCESS_TOKEN")
.header("content-type", "application/json")
.body("{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'PATCH',
url: 'https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID',
headers: {authorization: 'Bearer YOUR_ACCESS_TOKEN', 'content-type': 'application/json'},
data: {
options: {
client_id: 'thisismyid',
client_secret: 'thisismysecret',
profile: true,
upstream_params: {screen_name: {alias: 'login_hint'}}
}
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN",
@"content-type": @"application/json" };
NSDictionary *parameters = @{ @"options": @{ @"client_id": @"thisismyid", @"client_secret": @"thisismysecret", @"profile": @YES, @"upstream_params": @{ @"screen_name": @{ @"alias": @"login_hint" } } } };
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"PATCH"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => "{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}",
CURLOPT_HTTPHEADER => [
"authorization: Bearer YOUR_ACCESS_TOKEN",
"content-type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
payload = "{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}"
headers = {
'authorization': "Bearer YOUR_ACCESS_TOKEN",
'content-type': "application/json"
}
conn.request("PATCH", "/YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Patch.new(url)
request["authorization"] = 'Bearer YOUR_ACCESS_TOKEN'
request["content-type"] = 'application/json'
request.body = "{\"options\": {\"client_id\": \"thisismyid\", \"client_secret\": \"thisismysecret\", \"profile\": true, \"upstream_params\": {\"screen_name\": {\"alias\": \"login_hint\"}}}}"
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let headers = [
"authorization": "Bearer YOUR_ACCESS_TOKEN",
"content-type": "application/json"
]
let parameters = ["options": [
"client_id": "thisismyid",
"client_secret": "thisismysecret",
"profile": true,
"upstream_params": ["screen_name": ["alias": "login_hint"]]
]] as [String : Any]
let postData = JSONSerialization.data(withJSONObject: parameters, options: [])
let request = NSMutableURLRequest(url: NSURL(string: "https://YOUR_DOMAIN/api/v2/connections/YOUR-TWITTER-CONNECTION-ID")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Now, when you call the Authorize endpoint for a specific user, you can pass their email address in the login_hint
parameter.
https://YOUR_DOMAIN/authorize
?client_id=YOUR_CLIENT_ID
&response_type=token
&redirect_uri=https://YOUR_APP/callback
&scope=openid%20name%20email
&login_hint=john@gmail.com
Was this helpful?
And that value will in turn be passed along to the Twitter authorization endpoint in the screen_name
parameter.
https://api.twitter.com/oauth/authorize
?oauth_token=YOUR_TOKEN
&screen_name=john@gmail.com
Was this helpful?