1

I have written custom Auth Provider by extending AuthProviderPlugin class. I attached this Auth with Named Credentials with proper scope. The target system is responding with both access token and refresh token. Whenever I save the Named Credentials, the oAuth process is complete and I am able to make HTTP request with same. However, when the token expires , I am getting ' Script-thrown exception'. I have checked that on expiry the target returns 401, but somehow Salesforce is giving error. My AuthProvider Plugin code is as below:-

public with sharing class XYZAuthProvider extends Auth.AuthProviderPluginClass {

    public String getCustomMetadataType(){
        return 'SF_OB__XYZ_Auth_Setting__mdt';
    }

    public PageReference initiate(Map<String,String> authConfig,String state){
        String authUrlWithParams=authConfig.get('SF_OB__Auth_Url__c')+'?client_id='+authConfig.get('SF_OB__Client_Id__c')+'&redirect_uri='+authConfig.get('SF_OB__Redirect_Uri__c')+'&response_type=code&scope='+authConfig.get('SF_OB__Scope__c')+'&state='+state;
        return new PageReference(authUrlWithParams);

    }


    public Auth.AuthProviderTokenResponse handleCallback(Map<String,String> authConfig, Auth.AuthProviderCallbackState callbackState){

        Map<String,String> callbackParams=callbackState.queryParameters;
        String payload='code='+callbackParams.get('code')+'&client_id='+authConfig.get('SF_OB__Client_Id__c')+'&client_secret='+authConfig.get('SF_OB__Client_Secret__c')+'&grant_type=authorization_code&redirect_uri='+authConfig.get('SF_OB__Redirect_Uri__c')+'&scope=trust&state='+callbackParams.get('state');
        Http client=new Http();
        HttpRequest req=new HttpRequest();
        req.setEndPoint(authConfig.get('SF_OB__Access_Token_Url__c'));
        req.setHeader('Accept','application/json');
        req.setMethod('POST');
        req.setBody(payload);
        HttpResponse resp=client.send(req);
        XYZAuthProvider.XYZResponseStructure responseStruct=(XYZAuthProvider.XYZResponseStructure)JSON.deserialize(resp.getBody(),Type.forName('XYZAuthProvider.XYZResponseStructure'));
        System.debug('responseStruct'+responseStruct);
        return new Auth.AuthProviderTokenResponse('XYZAuthProvider',responseStruct.access_token,responseStruct.refresh_token,callbackParams.get('state'));



    }

    public Auth.UserData getUserInfo(Map<String,String> authConfig, Auth.AuthProviderTokenResponse response){
        System.debug('response'+response); 
        return new Auth.UserData('XYZAuthProvider', 'XYZ', 'XYZ', 'XYZ', '', '', 'XYZ', '', 'XYZ', '', null);
    }


    public class XYZResponseStructure{
        public string access_token;
        public string refresh_token;
        public string expires_in;
        public string token_type;
    }

1 Answer 1

1

I think it's because you're not handling the refresh method. Last week I wrote an Auth Provider that included the following method. I've done minimal testing, but it seems to work so far:

    public override Auth.OAuthRefreshResult refresh(Map<String,String> authProviderConfiguration, String refreshToken) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(authProviderConfiguration.get('Access_Token_URL__c'));
        req.setMethod('POST');
        req.setHeader('Content-Type','application/x-www-form-urlencoded');
        req.setHeader('Accept','application/json');

        String requestBody = '';
        requestBody += 'grant_type=refresh_token&';
        requestBody += 'client_id=' + authProviderConfiguration.get('Consumer_Key__c') + '&';
        requestBody += 'client_secret=' + authProviderConfiguration.get('Consumer_Secret__c') + '&';
        requestBody += 'refresh_token=' + refreshToken;

        req.setBody(requestBody);
        req.setHeader('Content-length', String.valueOf(requestBody.length()));

        Http http = new Http();
        HTTPResponse res = http.send(req);
        String responseBody = res.getBody();
        Integer statusCode = res.getStatusCode();

        OAuth2Response response = (OAuth2Response) JSON.deserialize(responseBody, OAuth2Response.class);

        if (statusCode != 200) {
            String errorMessage = 'Access Token refresh failed. Error: ' + res.toString();
            return new Auth.OAuthRefreshResult(response.access_token, response.refresh_token, errorMessage);
        }

        return new Auth.OAuthRefreshResult(response.access_token, response.refresh_token);
    }
1
  • Thanks, will work on this Jun 2, 2020 at 8:40

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .