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

如何在Acumatica框架中通过网络凭据认证创建共享路径文件

Got it, let's walk through how to implement creating files in an authenticated network share within the Acumatica framework. This involves handling credentials securely and working within Acumatica's runtime context to avoid permission issues, since the application pool identity typically won't have access to restricted network shares.

Approach Overview

We'll use a combination of:

  1. Acumatica's Secure Storage to store network credentials (no hardcoding!)
  2. .NET user impersonation to temporarily run code under the network user's identity
  3. Standard .NET file operations wrapped in Acumatica's error handling
Step 1: Store Credentials in Acumatica Secure Storage

First, add your network share credentials to Acumatica's Secure Storage (found under System > Management > Secure Storage). Create a new credential entry with a key like NetworkShare_Creds (you'll reference this key in code).

Step 2: Implement Impersonation Logic

We'll use P/Invoke calls to LogonUser to get a user token, then impersonate that user. Add this helper method to your custom Acumatica code (e.g., a BLC extension or action):

using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Principal;
using PX.Data;

public class NetworkShareHelper
{
    // P/Invoke declarations for Windows authentication
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool LogonUser(
        string lpszUsername,
        string lpszDomain,
        string lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        out IntPtr phToken);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    /// <summary>
    /// Impersonates a network user to access restricted resources
    /// </summary>
    public static WindowsImpersonationContext ImpersonateNetworkUser(PXSecureStorage.Credentials creds)
    {
        if (creds == null) throw new PXException("Network credentials not found.");

        IntPtr tokenHandle = IntPtr.Zero;
        try
        {
            // Use LOGON32_LOGON_NEW_CREDENTIALS for network access
            bool logonSuccess = LogonUser(
                creds.UserName,
                creds.Domain,
                creds.Password,
                9, // LOGON32_LOGON_NEW_CREDENTIALS
                0, // LOGON32_PROVIDER_DEFAULT
                out tokenHandle);

            if (!logonSuccess)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            WindowsIdentity userIdentity = new WindowsIdentity(tokenHandle);
            return userIdentity.Impersonate();
        }
        catch
        {
            if (tokenHandle != IntPtr.Zero) CloseHandle(tokenHandle);
            throw;
        }
    }
}
Step 3: Create the File in the Network Share

Now, in your custom action or event handler, retrieve the credentials, impersonate the user, and create the file. Here's an example using a button action in a BLC:

public class MyGraphExtension : PXGraphExtension<MyBaseGraph>
{
    public PXAction<MyDAC> CreateFileInShare;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Create File in Network Share")]
    public void createFileInShare()
    {
        // Ensure the user has permission to perform this action
        PXAccess.EnsurePermission<MyCustomPermission>();

        // Retrieve credentials from Secure Storage
        var networkCreds = PXSecureStorage.GetCredentials("NetworkShare_Creds");
        if (networkCreds == null)
        {
            throw new PXSetPropertyException("Network share credentials are not configured in Secure Storage.", PXErrorLevel.Error);
        }

        using (var impersonationContext = NetworkShareHelper.ImpersonateNetworkUser(networkCreds))
        {
            if (impersonationContext == null)
            {
                throw new PXException("Failed to impersonate the network user.");
            }

            try
            {
                // Define your network share path
                string networkPath = @"\\fileserver\shared\AcumaticaGeneratedFile.txt";
                
                // Create and write to the file
                using (StreamWriter writer = File.CreateText(networkPath))
                {
                    writer.WriteLine($"File created at {DateTime.Now:yyyy-MM-dd HH:mm:ss} from Acumatica.");
                }

                PXTrace.WriteInformation("Successfully created file at: {0}", networkPath);
                PXUIFieldAttribute.SetError<MyDAC.note>(Base.Caches[typeof(MyDAC)], null, "File created successfully!");
            }
            catch (Exception ex)
            {
                // Throw user-friendly error within Acumatica's context
                throw new PXSetPropertyException($"Failed to create file: {ex.Message}", PXErrorLevel.Error);
            }
            finally
            {
                // Always revert impersonation to avoid identity leaks
                impersonationContext.Undo();
            }
        }
    }
}
Key Considerations
  • Secure Credentials: Never hardcode usernames/passwords. Always use Acumatica's Secure Storage to protect sensitive information.
  • Permissions: Ensure the Acumatica application pool identity has the right to call LogonUser (adjust local security policy if needed). Also, assign a custom Acumatica permission to restrict who can run this action.
  • Cleanup: Always wrap impersonation in a using block or ensure Undo() is called to revert the identity.
  • Network Access: Verify the Acumatica server can reach the network share (test the path from the server first).
  • Error Handling: Use Acumatica's PXSetPropertyException to show user-friendly errors instead of raw exceptions.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:49:56