REST Overview Novel

oh found it - DST. Nice!

Do they do better than SHA2? Digging for that

1 Like

Nope, only SHA2. Hopefully they will be using 256 soon.

1 Like

Check out their trust chain doc

Short version they have been granted a trust cert and it’s being added to the different browsers and OSes (slowly). However before that’s all done they are cross signing their cert by IdenTrust (“DST Root CA X3” Root CA) a well known root authority that is established in all(most) platforms to establish trust even without the let’s Encrypt authority being trusted directly.

Revocation works the same as any other authority and any revoked cert is revoked on both sides.

1 Like

Actually I had forgotten, we have this site secured with let’s Encrypt too! :grinning:
And nobody even knew about it, check out the cert

1 Like

Hello All,

Product Owner for E10 REST Services here. I wanted to stop by and add that while the rest services are in tech preview mode in 10.1.500 we are actively seeking partners and customers who are interested in building solutions with them. Our primary motivation here is that we want to gather feedback from real world use of the services and encourage all of you early adopters get started with them. The whole point of these services is to enable you all to much more easily build integrations with Epicor and accelerate the ecosystem around Epicor Data. We’re big create more value than you capture fans, essentially.

We will be offering a more direct feedback channel for select customers and partners building against the tech preview as well as some additional resources like code samples, postman samples, etc. If you are interested in participating please feel free to reach out to me directly: bconner at epicor.

We’re all really excited to see what you all will build.

6 Likes

I am thinking it might be just a little more involved that a checkbox in the app server configuration :confused:
The following errors occurred while attempting to load the app.

  • No assembly found containing an OwinStartupAttribute.
  • No assembly found containing a Startup or [AssemblyName].Startup class.
    To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of “false” in your web.config.
    To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.
1 Like

I have it working on several boxes this way, just check this box in server config, hit deploy


Then enable HTTPS endpoint in your IIS Website (Assing CERT)

And navigate to
https://myserver/myinstance/api/help

1 Like

If you have the cert assigned to the web site it should be just the checkbox. Can you post the web.config (sanitized) It sounds like the REST section did not get enabled correctly for some reason.

1 Like

Don’t know if it makes a difference, but checkbox was not checked until today when 500.8 patch was applied

Web Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- Configuration section-handler declaration area. -->
  <configSections>
    <!-- this describes the settings for the Epicor Customization Framework (BPM, BAQ, etc) -->
    <section name="customizationSettings" type="Epicor.Customization.Configuration.CustomizationConfigurationSection, Epicor.Customization" />
  </configSections>
  <appSettings>
    <add key="AssemblyFileSystem" value="C:\inetpub\wwwroot\Epicor10.1\Server\Assemblies" />
    <add key="ThrowLockExceptions" value="false" />
    <add key="SystemCode" value="ERP" />
    <!-- queryMaxResultSet specifies maximum number of rows that will be returned by dynamic query-->
    <add key="queryMaxResultSet" value="0" />
    <!-- queryTimeout specifies seconds before query execution timeout-->
    <add key="queryTimeout" value="0" />
    <!-- Timeout for SQL commands. Value is in seconds. Zero turns off timeout. -->
    <add key="CommandTimeout" value="0" />
    <add key="LockTimeout" value="180000" />
    <!-- the network share where the client deployment / patches can be found-->
    <add key="ClientDeploymentFolder" value="" />
    <!-- Valid values: local, UDP or database -->
    <add key="NotificationType" value="database" />
    <!-- Valid values: 1024-65535. Choose a different port for each group of AppServers -->
    <add key="NotificationUdpPort" value="3100" />
    <!-- Used to limit number of loops in specific code logic. ~Maximum number of Stack Frames -->
    <add key="FrameLimit" value="2000" />
    <add key="SSRSRootFolder" value="" />
    <add key="SSRSBaseURL" value="http://localhost/ReportServer" />
  </appSettings>
  <customizationSettings di**bled="false" intermediateFolder="C:\inetpub\wwwroot\Epicor10.1\Server\BPM">
    <customizationStorage provider="SqlBlob" settings="" />
    <externalsStorage provider="FileSystem" settings="C:\inetpub\wwwroot\Epicor10.1\Server\Customization\Externals" />
    <types>
      <add name="BPM.BO" folder="BO" cacheName="Epicor_Ice_BPM_BO" />
      <add name="BPM.DT" folder="DT" cacheName="Epicor_Ice_BPM_BO" />
      <add name="BPM.Ubaq" folder="Ubaq" cacheName="Epicor_Ice_BPM_BO" />
      <add name="GenericImport" folder="EF" cacheName="Epicor_Erp_EF" />
      <add name="EDI" folder="OM\UD" cacheName="Epicor_Erp_EI" />
      <add name="ElectronicInterface" folder="EI" cacheName="Epicor_Erp_EI" />
      <add name="Expressions" folder="ECF" cacheName="Epicor_Erp_Expressions" />
      <add name="Posting" folder="PE" cacheName="Epicor_Ice_PE" />
      <add name="ProductConfigurator" folder="PC" cacheName="Epicor_Ice_PC" />
    </types>
  </customizationSettings>
  <connectionStrings>
    <add name="IceContext" connectionString="metadata=res://Ice.Data.Model/IceContext.csdl|res://Ice.Data.Model/IceContext.ssdl|res://Ice.Data.Model/IceContext.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(local);Initial Catalog=ADCO;User ID=**;Password=**;Min Pool Size=100;Max Pool Size=2000;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
    <add name="ErpContext" connectionString="metadata=res://Erp.Data.910100/ErpContext.csdl|res://Erp.Data.910100/ErpContext.ssdl|res://Erp.Data.910100/ErpContext.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=(local);Initial Catalog=ADCO;User ID=**;Password=**;Min Pool Size=100;Max Pool Size=2000;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
    <add name="ReportData" connectionString="Data Source=(local);Initial Catalog=EpicorReports;User ID=**;Password=**;Enlist=False;Min Pool Size=100;Max Pool Size=2000;MultipleActiveResultSets=True" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
  <system.serviceModel>
    <protocolMapping>
      <remove scheme="net.tcp" />
      <!--<add scheme="net.tcp" binding="customBinding" bindingConfiguration="TcpCompressedWindows" />-->
      <!--<add scheme="net.tcp" binding="customBinding" bindingConfiguration="TcpCompressedUsernameSslChannel" />-->
      <add scheme="net.tcp" binding="customBinding" bindingConfiguration="TcpCompressedUsernameWindowsChannel" />
      <!-- Requires a serverCertificate declared under serviceBehaviors to encrypt
      <remove scheme="http" />
      <add scheme="http" binding="wsHttpBinding" bindingConfiguration="SOAPHttp" />
      -->
      <!-- Enable for SOAP v1.1 over https
      <remove scheme="https" />
      <add scheme="https" binding="basicHttpBinding" bindingConfiguration="BasicHttp" />
      -->
    </protocolMapping>
    <services>
      <service name="Epicor.Web.OpenData">
        <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="RestHttps" contract="Epicor.Web.OpenData" />
      </service>
      <service name="Epicor.Web.RestAccess">
        <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="RestHttps" contract="Epicor.Web.RestAccess" />
      </service>
      <service name="Epicor.Web.TokenResource">
        <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="RestHttps" contract="Epicor.Web.TokenResource" />
      </service>
    </services>
    <bindings>
      <!--REST/OData - Authentication: Epicor Username - Channel encrypted via https  -->
      <webHttpBinding>
        <binding name="RestHttps" transferMode="Buffered">
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" />
        </binding>
      </webHttpBinding>
      <!--SOAP 1.1 - Authentication: Epicor Username - Channel encrypted via https -->
      <basicHttpBinding>
        <binding name="BasicHttp" maxReceivedMes**geSize="2147483647">
          <security mode="TransportWithMes**geCredential">
            <mes**ge clientCredentialType="UserName" />
          </security>
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" />
        </binding>
      </basicHttpBinding>
      <!--SOAP 1.2 - Authentication: Epicor Username - Mes**ge encrypted -->
      <wsHttpBinding>
        <binding name="SOAPHttp" maxReceivedMes**geSize="2147483647">
          <security mode="Mes**ge">
            <mes**ge clientCredentialType="UserName" />
          </security>
          <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" />
        </binding>
      </wsHttpBinding>
      <customBinding>
        <!--HTTPS - Authentication: Epicor Username - Channel encrypted via https -->
        <binding name="HttpBinarySslUsername">
          <binaryMes**geEncoding compressionFormat="Deflate">
            <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
          </binaryMes**geEncoding>
          <security authenticationMode="UserNameOverTransport" />
          <sslStreamSecurity />
          <httpTransport maxReceivedMes**geSize="102400000" />
        </binding>
        <!--NET.TCP - Authentication: Epicor Username - Channel encrypted via https -->
        <binding name="TcpCompressedUsernameSslChannel" openTimeout="00:10:00" receiveTimeout="9:00:00" sendTimeout="9:00:00">
          <CompressionEncoder>
            <binaryMes**geEncoding>
              <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
            </binaryMes**geEncoding>
          </CompressionEncoder>
          <security authenticationMode="UserNameOverTransport" />
          <sslStreamSecurity />
          <tcpTransport maxReceivedMes**geSize="2147483647" maxBufferSize="2147483647" transferMode="Buffered" />
        </binding>
        <!--NET.TCP - Authentication: Windows Credentials - Channel encrypted via Windows Trusted Domain between Client and Server -->
        <binding name="TcpCompressedWindows" openTimeout="00:10:00" receiveTimeout="9:00:00" sendTimeout="9:00:00">
          <CompressionEncoder>
            <binaryMes**geEncoding>
              <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
            </binaryMes**geEncoding>
          </CompressionEncoder>
          <windowsStreamSecurity />
          <tcpTransport maxReceivedMes**geSize="2147483647" maxBufferSize="2147483647" transferMode="Buffered" />
        </binding>
        <!--NET.TCP - Authentication: Epicor Username - Channel encrypted via Windows Trusted Domain between Client and Server -->
        <binding name="TcpCompressedUsernameWindowsChannel" openTimeout="00:10:00" receiveTimeout="9:00:00" sendTimeout="9:00:00">
          <CompressionEncoder>
            <binaryMes**geEncoding>
              <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxBytesPerRead="2147483647" />
            </binaryMes**geEncoding>
          </CompressionEncoder>
          <security authenticationMode="UserNameOverTransport" />
          <windowsStreamSecurity />
          <tcpTransport maxReceivedMes**geSize="2147483647" maxBufferSize="2147483647" transferMode="Buffered" />
        </binding>
      </customBinding>
    </bindings>
    <extensions>
      <bindingElementExtensions>
        <add name="CompressionEncoder" type="Epicor.ServiceModel.Configuration.CompressionEncodingElement, Epicor.ServiceModel, Culture=neutral" />
      </bindingElementExtensions>
    </extensions>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceThrottling maxConcurrentCalls="15120" maxConcurrentSessions="500000" maxConcurrentInstances="15120" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata httpGetEnabled="true" />
          <serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" mes**geAuthenticationAuditLevel="Failure" suppres**uditFailure="true" />
          <serviceCredentials>
            <!-- Uncomment for https. Set FindType and Value based on your Certificate
            <serviceCertificate x509FindType="FindBySubjectName" findValue="Epicor**mple" storeLocation="LocalMachine" storeName="My" />
            -->
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Ice.Security.UsernameValidator, Epicor.Ice, Culture=neutral" />
            <clientCertificate>
              <authentication revocationMode="NoCheck" certificateValidationMode="PeerOrChainTrust" />
            </clientCertificate>
          </serviceCredentials>
          <!--
          Note: This service authorization entry must exist to validate calls destined for ICE or Ice-derived application services.
          -->
          <serviceAuthorization serviceAuthorizationManagerType="Ice.Security.AuthorizationManager, Epicor.Ice, Culture=neutral" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.tran**ctions>
    <defaultSettings timeout="05:00:00" />
  </system.tran**ctions>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Assemblies/WebApi" />
    </assemblyBinding>
  </runtime>
  <system.webServer>
    <modules>
      <remove name="WebDAVModule" />
      <remove name="Owin" />
      <add name="Owin" type="Microsoft.Owin.Host.SystemWeb.OwinHttpModule, Microsoft.Owin.Host.SystemWeb" />
    </modules>
    <handlers>
      <remove name="WebDAV" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
  </system.webServer>
</configuration>
1 Like

Is this correct location for self signed cert?

[cid:image001.png@01D24A52.18473820]

1 Like

Yeah Bernie your Web.Config got screwed up some how, Yours (Left) mine (Right)
https://www.diffchecker.com/wg4KoIJD

I’d recommed you just delete / re-deploy your 500 just delete the Application, AppPool, LocalClient folder and Config in the Deployment Directory then redeploy with the same name (so it doesn’t break your existing clients)
Casue your web config is wayyy out of wack

1 Like

It is just a demo server – I can delete the app sever and directories and re-deploy
I am the only existing client :wink:

2 Likes

Subject name for the certificate you use in Https setting must correspond to the site URL you connect.
So for localhost site, subject name in the certificate must be CN=localhost. (also localhost may be specified as SAN)

1 Like

Re-deployed as new app server and works OK
The upgraded app server di not…

1 Like

Thanks for the data point! I’ll keep a look out for similar.

1 Like

PHP example with UD05 on 10.1.500 works pretty slick. The Filter formatting is a bit weird but it works for me.

http://www.wisconsinconverting.com/epicor/MachineMapEpicor10.php

Physical machine locations / status

2 Likes

@Bart_Elia when I run a GET on LaborDtl without a filter I get results. When I run it with a filter I get a 200 response but nothing back for data. I ran a query against my DB to verify I actually do have records where ActiveTrans eq true but nuffin… thoughts?

Testing it out no data.

Verified 3 records in DB

A serious wtf moment for me here

Just for kicks i tried the Labors vs LaborDtls methods and Labors worked with “Labors?%24filter=EmployeeNum%20eq%20’102’&%24orderby=ClockInDate%20asc” LaborDtls did not. It appears to be just an issue with the LaborDtls listing method

1 Like