I am trying to connect to Salesforce from an external server and I am doing this via the OAuth 2.0 JWT flow to gain authorization into Salesforce.

I construct the JWT token from the external server and hit a connected app within Salesforce. When I post a request with this JWT, I get an access token - which is correct. I am trying to reconstruct another JWT and do another request with this new JWT to Salesforce. I however get the same access token again and not a fresh access token. Salesforce allows multi-session login using the same user name but the OAuth JWT flow doesn't seem to be having a multi-session login access. Could you tell me if I need to pass any additional info like IP and browser setting with the OAuth request.

Do let me know if I can achieve a concurrent multisession (with different session IDs) login using the JWT OAuth flow as this is critical for my solution.


If the same app asks for an access token for the same user, you'll get the existing access token. The only way I know of for you to get a new token is to revoke the existing one.

What is the use case? Why do you need different access tokens?


I am also facing similar kind of issue. OAuth returns same session id on multiple request.

Expecting different access token for each user. Please review the below code and suggest me for any changes to generate different access tokens per user based. I am trying to integrate two different domain applications. We have n number of users for the first application. What is the parameters that can change in claimset to generate user based access token?

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SFDCCSCIntegration
    public partial class _Default : System.Web.UI.Page
        protected void Page_Load(object sender, EventArgs e)

        public static dynamic GetAccessToken()
            // Load the certificate
            var certificate = new X509Certificate2(@"C:\Users\ns\Desktop\cert\myrsacert.pfx");

            # region variables
            // create header
            var header = new { alg = "RS256" };

            // create claimset
            var expiryDate = GetExpiryDate();
            var claimset = new
                iss = "3MVG9MHOv_bskkhRDNAVrQXJIa4WlEgqbpQ0G4xBaFOKhpLZejvQyb62YtoT3JYEu3ltNhcHTcxm.5NYHHgxL",
                sub = "myemail.com",
                aud = "https://login.salesforce.com",
                jti ="10000000000000000003",
                exp = GetExpiryDate()


            # endregion

            var ser = new JavaScriptSerializer();

            # region Header Encoding and Base64Url conversion
            // encoded header
            var headerSerialized = ser.Serialize(header);
            var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
            var headerEncoded = ToBase64UrlString(headerBytes);
            # endregion

            # region ClaimSet Encoding and Base64Url conversion
            // encoded claimset
            var claimsetSerialized = ser.Serialize(claimset);
            var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
            var claimsetEncoded = ToBase64UrlString(claimsetBytes);
            # endregion

            // input
            var input = headerEncoded + "." + claimsetEncoded;
            var inputBytes = Encoding.UTF8.GetBytes(input);

            # region - Signature Section
             //signature section not needed as of now.
            var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
            var cspParam = new CspParameters
                KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
                KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2
            var aescsp = new RSACryptoServiceProvider(cspParam) { PersistKeyInCsp = false };
            var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
            var signatureEncoded = ToBase64UrlString(signatureBytes);
            # endregion 

            // jwt
            var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;
            //var jwt ="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTU5NzU4MjcsImV4cCI6MTQ0NzUxMTgyNywiYXVkIjoiaHR0cHM6Ly90ZXN0LnNhbGVzZm9yY2UuY29tIiwic3ViIjoiIn0.lfgMfApLPn8WQZo8ftWgCbYN2MpMqrRbE4Kovym73t4";
            # region Posting the request to SFDC
            var client = new WebClient();
            client.Encoding = Encoding.UTF8;
            var uri = "https://test.salesforce.com/services/oauth2/token";
            var content = new NameValueCollection();

            content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";
            content["assertion"] = jwt;

                string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));

                var result = ser.Deserialize<dynamic>(response);
                var resultAccessToken = result["access_token"].ToString();
                return result;
            catch (Exception ex)
                return null;
            # endregion

        private static int GetExpiryDate()
            var utc0 = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            var currentUtcTime = DateTime.UtcNow;

            var exp = (int)currentUtcTime.AddMinutes(4).Subtract(utc0).TotalSeconds;

            return exp;

        static string ToBase64UrlString(byte[] input)
            return Convert.ToBase64String(input).TrimEnd('=').Replace('+', '-').Replace('/', '_');

Check 'Lock sessions to the IP address from which they originated' in session settings. It worked for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.