You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

扩展Auth.AuthProviderPluginClass时如何自定义state参数?

自定义AuthProvider State变量问题解决方案

核心原因

OAuth的state参数用于防范CSRF攻击,不管是Salesforce的AuthProvider框架还是第三方OAuth服务,都要求state必须是随机生成、可验证的有效取值:

  • 移除state会触发第三方服务的必填校验,导致Remote_Error
  • 使用固定虚拟值(如test)会因无法通过验证逻辑,触发No_Oauth_State错误

解决方法

1. 利用Salesforce框架自动处理State(推荐)

继承Auth.AuthProviderPluginClass的自定义类,直接调用父类方法即可让框架自动完成state的生成、会话存储和回调验证,无需手动实现复杂逻辑:

自定义AuthProvider代码实现

public class CustomAuthProvider extends Auth.AuthProviderPluginClass {
    public override PageReference initiate(Map<String, String> providerConfiguration, String state) {
        // 调用父类方法,自动生成并处理state
        PageReference authPage = super.initiate(providerConfiguration, state);
        
        // 添加自定义授权参数(如scope、重定向地址)
        authPage.getParameters().put('scope', providerConfiguration.get('Scope__c'));
        authPage.getParameters().put('redirect_uri', providerConfiguration.get('Redirect_URI__c'));
        
        return authPage;
    }

    public override Auth.AuthProviderPluginResult handleCallback(Map<String, String> providerConfiguration, Map<String, String> callbackParameters) {
        // 父类自动完成state验证,无需手动处理
        Auth.AuthProviderPluginResult baseResult = super.handleCallback(providerConfiguration, callbackParameters);
        
        // 在此添加自定义token解析、用户映射等逻辑
        return baseResult;
    }
}

调用initiate的代码修改

无需手动传入固定state,直接传null让框架自动生成:

// 获取MDT记录信息
AuthCredential__mdt authCredentialMDT = [SELECT Id, Client_Id__c, Auth_URL__c, Scope__c, Redirect_URI__c FROM AuthCredential__mdt WHERE DeveloperName =:authProviderDeveloperName];
Map<String, String> stringMap = new Map<String, String>();
Map<String, Object> objectMap = (Map<String, Object>)(JSON.deserializeUntyped(JSON.serialize(authCredentialMDT)));
for(String key : objectMap.keySet()) {stringMap.put(key, String.valueOf(objectMap.get(key)));}

// 获取授权页面URL,传入null让框架自动生成state
CustomAuthProvider authMethod = new CustomAuthProvider();
PageReference newPage = authMethod.initiate(stringMap, null);
result = newPage.getUrl();

2. 自定义State生成与验证(完全控制场景)

如果需要自定义state的生成规则,必须确保state在授权发起时存储到会话,回调时取出验证:

自定义AuthProvider代码实现

public class CustomAuthProvider extends Auth.AuthProviderPluginClass {
    public override PageReference initiate(Map<String, String> providerConfiguration, String state) {
        // 生成随机唯一的state值
        String customState = String.valueOf(Crypto.getRandomLong());
        // 将state存储到用户会话,用于后续验证
        ApexPages.currentPage().getSession().put('CustomAuth_State', customState);
        
        // 构建授权URL并携带自定义state
        String authUrl = providerConfiguration.get('Auth_URL__c');
        PageReference authPage = new PageReference(authUrl);
        authPage.getParameters().putAll(new Map<String, String>{
            'client_id' => providerConfiguration.get('Client_Id__c'),
            'redirect_uri' => providerConfiguration.get('Redirect_URI__c'),
            'scope' => providerConfiguration.get('Scope__c'),
            'state' => customState
        });
        
        return authPage;
    }

    public override Auth.AuthProviderPluginResult handleCallback(Map<String, String> providerConfiguration, Map<String, String> callbackParameters) {
        // 取出会话中存储的state
        String storedState = (String)ApexPages.currentPage().getSession().get('CustomAuth_State');
        String receivedState = callbackParameters.get('state');
        
        // 验证state有效性
        if (String.isBlank(storedState) || !storedState.equals(receivedState)) {
            throw new Auth.AuthProviderException('No_Oauth_State: State was not valid');
        }
        
        // 清除会话中的state,避免重复使用
        ApexPages.currentPage().getSession().remove('CustomAuth_State');
        
        // 后续处理token获取、用户映射等逻辑
        return new Auth.AuthProviderPluginResult(...);
    }
}

3. 额外校验项

  • 确认Auth.Provider、Named Credential中的Redirect URI与MDT记录、第三方OAuth服务的配置完全一致,否则会触发state验证失败
  • 检查通过Tooling API创建的Auth Provider记录,确保Consumer Key、Consumer Secret等核心配置无误

内容的提问来源于stack exchange,提问作者islandtimesfdcdeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:05:18