1

In trying to talk with an auth provider to get a token response for a process I'm working on I'm running into issues with the redirect/callback portion of the communication after logging in to the provider.

I keep getting a 'No_Oauth_State: State was not valid' after entering my credentials. The dev I'm working with on the other side shows that not only is the token being successfully issued, but they're returning the state value that I send them, so I'm not sure why that particular error.

It doesn't even look like it's making it to my handleCallback method where I could pull more details as to why I'm getting the error, and none of my logs are picking up anything either, as if SF is rejecting any return communication immediately, so any insight into what I'm doing wrong, or how I could advise the other dev to tweak their response would be appreciated.

Here's the class:

global class OpenIdConnectProcessing extends Auth.AuthProviderPluginClass{

public String redirectUrl; 
private String key;
private String secret;
private string scope;
private String authUrl;  
private String accessTokenUrl;
private String state; 
@Testvisible private Static AuthProvider__mdt authProviderSettings = [SELECT Id, DeveloperName, MasterLabel, NamespacePrefix, QualifiedApiName, State__c, Access_Token_URL__c, Callback_URL__c, Client_ID__c, Client_Secret__c, Provider_Name__c, Scope__c FROM AuthProvider__mdt WHERE DeveloperName = 'SamtecTest' LIMIT 1];
private String customMetadataTypeApiName = 'AuthProvider__mdt'; 
      
/**
Debugging purposes to have visibility as to when the class is being instantiated for testing.
**/
public OpenIdConnectProcessing(){
    super();
    System.debug('Constructor called');
    }

global String getCustomMetadataType(){
    return customMetadataTypeApiName;
    }  

public Pagereference onLoad(){
    authUrl = authProviderSettings.Access_Token_URL__c; 
    key = authProviderSettings.Client_ID__c;
    secret = authProviderSettings.Client_Secret__c;
    redirectUrl = authProviderSettings.Callback_URL__c;
    state = authProviderSettings.State__c;
    scope = authProviderSettings.Scope__c;
    String url = authUrl + '?client_id='+ key +'&secret=' + secret +'&scope=' + scope + '&redirect_uri='+ redirectUrl + '&state=' + state + '&response_mode=query' + '&response_type=code';
    system.debug('URL: ' + url); 
    return new PageReference(url);
    }

global PageReference initiate(Map<string,string> authProviderConfiguration, String stateToPropagate){ 
    authUrl = authProviderSettings.Access_Token_URL__c; 
    key = authProviderSettings.Client_ID__c;
    secret = authProviderSettings.Client_Secret__c;
    redirectUrl = authProviderSettings.Callback_URL__c;
    state = authProviderSettings.State__c;
    scope = authProviderSettings.Scope__c;
    String url = authUrl + '?client_id='+ key +'&secret=' + secret +'&scope=' + scope + '&redirect_uri='+ redirectUrl + '&state=' + state + '&response_mode=query' + '&response_type=code';
    system.debug('URL: ' + url); 
    return new PageReference(url); 
    } 

global Auth.AuthProviderTokenResponse handleCallback(Map<string,string> authProviderConfiguration, Auth.AuthProviderCallbackState state){ 
    key = authProviderConfiguration.get('Key__c'); 
    secret = authProviderConfiguration.get('Secret__c'); 
    accessTokenUrl = authProviderConfiguration.get('Access_Token_Url__c'); 
    Map<String,String> queryParams = state.queryParameters; 
    String code = queryParams.get('code'); 
    String sfdcState = queryParams.get('state'); 
    HttpRequest req = new HttpRequest(); 
    String url = accessTokenUrl+'?code=' + code + '&client_id=' + key + '&client_secret=' + secret; 
    req.setEndpoint(url); 
    req.setHeader('Content-Type','application/xml'); 
    req.setMethod('GET'); 
        
    Http http = new Http(); 
    HTTPResponse res = http.send(req); 
    String responseBody = res.getBody(); 
    string token = getTokenValueFromResponse(responseBody, 'Token', null); 
    return new Auth.AuthProviderTokenResponse('Test', token,'refreshToken', sfdcState); 
    } 

global Auth.UserData getUserInfo(Map<string,string> authProviderConfiguration, Auth.AuthProviderTokenResponse response){ 
    String token = response.oauthToken; 
    HttpRequest req = new HttpRequest(); 
    req.setHeader('Authorization', 'OAuth ' + token); 
    req.setHeader('Content-Type','application/xml'); 
    req.setMethod('GET'); 
    
    Http http = new Http(); 
    HTTPResponse res = http.send(req); 
    String responseBody = res.getBody(); 
    Map<String,String> provMap = new Map<String,String>(); 
    provMap.put('what1', 'noidea1'); 
    provMap.put('what2', 'noidea2'); 
    return new Auth.UserData(null, null, null, null, null, 'what', null, null, 'test', null, provMap); 
    } 
        
private String getTokenValueFromResponse(String response, String token, String ns){ 
    Dom.Document docx = new Dom.Document(); 
    docx.load(response); 
    String ret = null; 
    dom.XmlNode xroot = docx.getrootelement() ; 
    if(xroot != null){ 
        ret = xroot.getChildElement(token, ns).getText(); 
        } 
        return ret; 
    }

}

Your Answer

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

Browse other questions tagged or ask your own question.