I'm using Open Id for Salesforce, I followed the Doc from https://help.salesforce.com/articleView?id=sso_provider_azure.htm and could able to login to Salesforce using Azure AD credentials successfully. Now, when I'm trying to get access token with Auth.AuthToken.getAccessToken(ProviderId, 'Open ID Connect') it returns null. So I started writing an apex code and a Visualforce page as below to get the authentication Code from Azure AD and then to get an Access Token using Azure AD OAuth 2.0 code grant flow.

Apex class

public with sharing class oAuth_Controller{

    public string theCode {get;set;}
    public string theTokenResponse {get;set;}

    public pagereference auth_Step_1(){

        String auth_url = 'https://login.microsoftonline.com/miraclesoftinc.onmicrosoft.com/oauth2/authorize';
        String params = '?response_type=code' +
                        '&client_id=cb618894-d01e-4b84-a5fd-41ebfe94fs15' +
                        '&redirect_uri=https%3A%2F%2Fmsssf-dev-ed.my.salesforce.com%2Fservices%2Fauthcallback%2FAzureAuth' + 
                        '&scope=openid' +  
        pageReference pr = New PageReference(auth_url + params);            
        return pr;

    public pagereference auth_Step_2(){

        if(apexPages.currentPage().getParameters().get('state') != '12345')
            return null;

        theCode = apexPages.currentPage().getParameters().get('code');

        HttpRequest req = new HttpRequest();
        Http http = new Http();

        String auth_url = 'https://login.microsoftonline.com/miraclesoftinc.onmicrosoft.com/oauth2/token';
        String params =  
                            '?code=' + apexPages.currentPage().getParameters().get('code') +
                            '&grant_type=authorization_code' + 
                            '&client_id=cb618894-d01e-4b84-a5fd-41ebfe94fs15' +
                            '&client_secret=IryuiX1ftk/A0BgbS0npQ4XQTbk2BmAqqLsPhIeqzZ0c=' + 

        req.setEndpoint(auth_url + params);

        HTTPResponse resp = http.send(req);

        theTokenResponse = resp.getBody();

        return null;


Visualforce page

<apex:page controller="oAuth_Controller" action="{!auth_step_2}">
  <apex:form >
    <apex:commandButton action="{!auth_Step_1}" value="Start" reRender="results"/>
  <apex:outputPanel id="results">

Now, I'm getting the below error. Can anyone please help me, how to get the Oauth State in Salesforce.

enter image description here.



The reason you're seeing this error is because of the way you're implemented the use of the OAuth State attribute in your Controller (it doesn't belong there as part of string that's a constant).

From the OAuth Documentation:


RECOMMENDED. An opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. The parameter SHOULD be used for preventing cross-site request forgery as described in Section 10.12.

10.12. Cross-Site Request Forgery Cross-site request forgery (CSRF) is an exploit in which an attacker causes the user-agent of a victim end-user to follow a malicious URI (e.g., provided to the user-agent as a misleading link, image, or redirection) to a trusting server (usually established via the presence of a valid session cookie).

A CSRF attack against the client’s redirection URI allows an attacker to inject its own authorization code or access token, which can result in the client using an access token associated with the attacker’s protected resources rather than the victim’s (e.g., save the victim’s bank account information to a protected resource controlled by the attacker).

The client MUST implement CSRF protection for its redirection URI. This is typically accomplished by requiring any request sent to the redirection URI endpoint to include a value that binds the request to the user-agent’s authenticated state (e.g., a hash of the session cookie used to authenticate the user-agent). The client SHOULD utilize the "state" request parameter to deliver this value to the authorization server when making an authorization request.

Once authorization has been obtained from the end-user, the authorization server redirects the end-user’s user-agent back to the client with the required binding value contained in the "state" parameter. The binding value enables the client to verify the validity of the request by matching the binding value to the user-agent’s authenticated state. The binding value used for CSRF protection MUST contain a non-guessable value (as described in Section 10.10), and the user-agent’s authenticated state (e.g., session cookie, HTML5 local storage) MUST be kept in a location accessible only to the client and the user-agent (i.e., protected by same-origin policy).

A CSRF attack against the authorization server’s authorization endpoint can result in an attacker obtaining end-user authorization for a malicious client without involving or alerting the end-user. The authorization server MUST implement CSRF protection for its authorization endpoint and ensure that a malicious client cannot obtain authorization without the awareness and explicit consent of the resource owner.

As you can see, this is about verifying the redirection that's done is legit to prevent CSRF. The method you're utilizing doesn't do that which is why you're receiving the error message you are from Salesforce.

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.