• Home
  • Forums
  • SBM
  • I would know when a notification was last triggered.

API Authentication Question

0
Hello,

I have created a small .NET app where when a user creates a new client in our CRM, it will also create that new client in SBM, to eliminate double entry. It works fine but during my dev/testing, I've used my own credentials to authenticate to SBM.

We use SSO for SBM. We are required to change our passwords every 4 months so if I kept my (or any other users) credentials in the code, I'd have to remember to change the password in this app as well. I'd like to avoid having to do that. So my question is, what is the best way to authenticate to SBM via the API to add new items in this scenario?

Thanks.
Like
Responses (3)
  • Accepted Answer

    Friday, May 31 2019, 12:33 PM - #Permalink
    0
    Hi Mike,

    You can make your .NET program a trusted delegator. It will utilize a service account to login to SBM and get an SSO token on behalf of the user that wants make the update. Then, the program would make the update via the JSON API as the user.

    Or we have another feature where the .NET service account can acquire a token on its own behalf using Windows Authentication. Then, you would update the ticket as service account or as the service account on behalf of another user.

    Which use case are you looking to do?

    David Goodale
    The reply is currently minimized Show
  • Accepted Answer

    Wednesday, June 05 2019, 06:16 PM - #Permalink
    0
    Hi David,

    First, thanks very much for the reply.

    My app is actually a CRM plugin so it's just a .DLL. I'm not sure how I would make it a trusted delegator. Either option you listed sounds reasonable but I'm not sure how to go about implementing them. Is there any documentation I can find that would walk me through that?

    Also, in this scenario where we're adding items to an auxiliary table, does the user in the context need to be an admin or otherwise have elevated privileges? Or can any standard user do that?

    Thanks again!

    Mike
    The reply is currently minimized Show
  • Accepted Answer

    Friday, June 07 2019, 11:07 AM - #Permalink
    1
    Hi Mike,

    The way this would work is to acquire an authentication token from the SSO IdP to use it in the SOAP (see KB S140623) or [JSON API] header.

    Options for getting tokens:


    Use NTLM / IWA to authenticate to a custom SSO IdP REST endpoint.
    Use set SBM to use internal user / passwords for web services.


    Option 1
    We create a custom endpoint for the SBM SSO IdP REST services. We would protect it with IWA. We can use the IWA endpoint to request SSO tokens with Windows Credentials. Does the CRM have access to the user's Windows Credentials? If the DLL function is called within the context of a user's web session then the answer may be yes.

    If you do not have access to the user's credentials once in the DLL context then perhaps, you can use the credentials of the CRM Windows service. If the CRM service is running as a domain account then you can use those credentials to access the REST endpoint.

    To do this, edit the idp/WEB-INF/web.xml and add the following definition [iwa-filter] above (not in) the Configurator marker lines:



    After this is set, we would have a new endpoint that would provide authentication:

    [iwa-ep] ort/idp/services/rest/iwa" target="_blank">http://hostname:port/idp/services/rest/iwa

    You can make a HTTP GET call on [iwa-ep] to request tokens. Two headers that need to be set are "Accept" and "Content-Type" which have to be set to "application/json" as per JSON specs. If the user is not present, SSO server will return [sso-invaliduser-error]. If the call is successful the server will return [sso-ok] JSON response.

    Option 2
    If SBM is set to use internal passwords[1], you still can call the regular endpoint "http://hostname:port/idp/services/rest" and use JSON request to request tokens. Since this is JSON call, it must be POST with same requirements on the request headers. I am attaching the JSON request and response JSON schemas that you can use but just an example how to get a token with username of "gstanchev" and password "secret":

    {
    "credentials": {
    "username": "gstanchev",
    "password": "secret"
    }
    }

    Hope this helps.

    Regards,
    David Goodale


    [JSON API]
    http://help.serena.com/doc_center/sbm/ver11_6/json_api_guide.pdf

    [sso-invaliduser-error]
     
    {"status":"Error","error":{"code":"FailedAuthentication","lang":"en","reason":"Authentication failed","detail":"Invalid User ID or Password"}'}


    [sso-ok]
     
    {"status":"OK","lifetime":{"created":1530654278000,"expires":1530683078000},"token":{"tokenType":"SSO","encoding":"base64","value":"PHNhbWw6QXNzZXJ0aW9uIHhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMDphc3NlcnRpb24iIEFzc2VydGlvbklEPSJ1cm46dXVpZDo4OURCOEIxODBGREJFQjM1NjgxNTMwNjU0Mjc4MDEzIiBJc3N1ZUluc3RhbnQ9IjIwMTgtMDctMDNUMjE6NDQ6MzguMFoiIElzc3Vlcj0iaHR0cHM6Ly9sb2NhbGhvc3QvaWRwL3NlcnZpY2VzL1RydXN0IiBNYWpvclZlcnNpb249IjEiIE1pbm9yVmVyc2lvbj0iMSI+PHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMTgtMDctMDNUMjE6NDQ6MzguMFoiIE5vdE9uT3JBZnRlcj0iMjAxOC0wNy0wNFQwNTo0NDozOC4wWiI+PHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbkNvbmRpdGlvbj48c2FtbDpBdWRpZW5jZT51cmk6b3JnOmVjbGlwc2U6YWxmOnNzbzpyZWx5aW5ncGFydHk6YW5vbnltb3VzOmFub255bW91czphbm9ueW1vdXM8L3NhbWw6QXVkaWVuY2U+PC9zYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb25Db25kaXRpb24+PC9zYW1sOkNvbmRpdGlvbnM+PHNhbWw6QXV0aGVudGljYXRpb25TdGF0ZW1lbnQgQXV0aGVudGljYXRpb25JbnN0YW50PSIyMDE4LTA3LTAzVDIxOjQ0OjM4LjBaIiBBdXRoZW50aWNhdGlvbk1ldGhvZD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4wOmFtOnVuc3BlY2lmaWVkIj48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJZGVudGlmaWVyIEZvcm1hdD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6MS4xOm5hbWVpZC1mb3JtYXQ6dW5zcGVjaWZpZWQiPmdzdGFuY2hldjwvc2FtbDpOYW1lSWRlbnRpZmllcj48c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjxzYW1sOkNvbmZpcm1hdGlvbk1ldGhvZD51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjA6Y206YmVhcmVyPC9zYW1sOkNvbmZpcm1hdGlvbk1ldGhvZD48L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj48L3NhbWw6U3ViamVjdD48L3NhbWw6QXV0aGVudGljYXRpb25TdGF0ZW1lbnQ+PHNhbWw6QXR0cmlidXRlU3RhdGVtZW50PjxzYW1sOlN1YmplY3Q+PHNhbWw6TmFtZUlkZW50aWZpZXIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDp1bnNwZWNpZmllZCI+Z3N0YW5jaGV2PC9zYW1sOk5hbWVJZGVudGlmaWVyPjxzYW1sOlN1YmplY3RDb25maXJtYXRpb24+PHNhbWw6Q29uZmlybWF0aW9uTWV0aG9kPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMDpjbTpiZWFyZXI8L3NhbWw6Q29uZmlybWF0aW9uTWV0aG9kPjwvc2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uPjwvc2FtbDpTdWJqZWN0PjxzYW1sOkF0dHJpYnV0ZSBBdHRyaWJ1dGVOYW1lPSJJZGVudGl0eVN0b3JlVHlwZSIgQXR0cmlidXRlTmFtZXNwYWNlPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FsZi9zc28vMS4wL2NsYWltcyI+PHNhbWw6QXR0cmlidXRlVmFsdWU+QUU8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48c2FtbDpBdHRyaWJ1dGUgQXR0cmlidXRlTmFtZT0iSWRlbnRpdHlTdG9yZVVSSSIgQXR0cmlidXRlTmFtZXNwYWNlPSJodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2FsZi9zc28vMS4wL2NsYWltcyI+PHNhbWw6QXR0cmlidXRlVmFsdWU+aHR0cDovL29yYm1wZC0wM2Y0MmRmNS9nc29hcC9nc29hcF9zc2wuZGxsP3NibWludGVybmFsc2VydmljZXM3Mjwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBBdHRyaWJ1dGVOYW1lPSJVc2VyTmFtZXNwYWNlIiBBdHRyaWJ1dGVOYW1lc3BhY2U9Imh0dHA6Ly9zY2hlbWFzLnNlcmVuYS5jb20veG1sL3dzL3NibS9zc28vY2xhaW1zIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZT4wMDAwMDwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3NhbWw6QXR0cmlidXRlPjxzYW1sOkF0dHJpYnV0ZSBBdHRyaWJ1dGVOYW1lPSJUaWNrZXRUeXBlIiBBdHRyaWJ1dGVOYW1lc3BhY2U9Imh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvYWxmL3Nzby8xLjAvY2xhaW1zIj48c2FtbDpBdHRyaWJ1dGVWYWx1ZT5UR1Q8L3NhbWw6QXR0cmlidXRlVmFsdWU+PC9zYW1sOkF0dHJpYnV0ZT48L3NhbWw6QXR0cmlidXRlU3RhdGVtZW50PjxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxkczpTaWduZWRJbmZvPjxkczpDYW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIiAvPjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNyc2Etc2hhMjU2IiAvPjxkczpSZWZlcmVuY2UgVVJJPSIjdXJuOnV1aWQ6ODlEQjhCMTgwRkRCRUIzNTY4MTUzMDY1NDI3ODAxMyI+PGRzOlRyYW5zZm9ybXM+PGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIiAvPjxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiIC8+PC9kczpUcmFuc2Zvcm1zPjxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIgLz48ZHM6RGlnZXN0VmFsdWU+OUE1YUFXNnEwN0QrbzRGQ1VyYWhpUGpNRXM0PTwvZHM6RGlnZXN0VmFsdWU+PC9kczpSZWZlcmVuY2U+PC9kczpTaWduZWRJbmZvPjxkczpTaWduYXR1cmVWYWx1ZT55WlJWUTk3d3BLN2R5V3hncEE5QXYwbFNqRFA5QnU0V0xnU3BNVlJ3TGNmS3R3VS9hNlBkM256aGxFTmJJazYzWndaaGU0bk9CMGNoTXBvb0JxN2lYZ2dyM1d2R01YNVpyZFY0ZldUUThkWXIrdS9ZTEhwdDN6OFJBVldwTmUra2M5UHlhN0hFaVBVTS9tWXVzRGpKYXNmUXcxbk9JM1FUcm94aUF2d3BEUHpTZnNHbFFSNmpIb20rNlN2U2p5cEpmcUw1OUdWT1lCOFY4VlNTNHd1Y3NlS2RHeFEwc2Jhd3JTTDZ5NHpoN3ZmdjB4SFNFZzlqSm9SWWt6UWNYK0tqV0RpMFladE94RnhORkl4VHRiRW0wc2tHMUIwdjhJUktSbFIwQkY1QzRiem11dkJhV1FvK1F2aG53cWhPUldvbjRxeDYwdXljRlhneXc1cy9lcERxa1E9PTwvZHM6U2lnbmF0dXJlVmFsdWU+PGRzOktleUluZm8+PGRzOktleVZhbHVlPjxkczpSU0FLZXlWYWx1ZT48ZHM6TW9kdWx1cz45L0ZNQnpEMGxIWkdRemdXcVNJZExiY3FmanJqOStQWFpjZUhOMEd1cTFsYVplV2VsNUJEL3huMWVzMzROT0V1TnJ5dThDVGZWTFlDZnNjMXlQU2pobmNVTTNGemNkQVVqNnRaNU5RYm90ZkxLbEZZQ0tmZ2J4SkMwZHVsWUx1ZTlSZlpCTnZWR05TWFFkVURNZEJtR2g4ekVUK3J4WVJENmdUanl4SU9DYjh5L0xNRnNxOUQ4eWdtYXRCVEJhdjg1WTJmVFhod2prZDJ3dEM2MnJ0LzJFVlFXdzdlUFpSZWdDV2VkSVU5UXUwY2VWY0FPc2JwQ01XNzZNcnlOUGpKMnhpTG9La3ZFN0EvMEVFZ2V3Q0UwYzhHYzlNUzh2cmhlM0lJaDI2L2dqTWkzdDd1L1RPbldPY1IrQXFsSVM4aXprdWFER3o0WS81YUkrUzVaSUhPWXc9PTwvZHM6TW9kdWx1cz48ZHM6RXhwb25lbnQ+QVFBQjwvZHM6RXhwb25lbnQ+PC9kczpSU0FLZXlWYWx1ZT48L2RzOktleVZhbHVlPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVyZT48L3NhbWw6QXNzZXJ0aW9uPg=="}'}



    [iwa-filter]
     
    <!-- ========================================================== -->
    <!-- Negotiate (NTLM & Kerberos) authentication via Waffle. -->
    <!-- See Waffle documentation for more info at -->
    <!-- http://http://dblock.github.io/waffle/ -->
    <!-- ========================================================== -->
    <filter>
    <filter-name>WaffleIWAFilter</filter-name>
    <filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>
    <init-param>
    <param-name>principalFormat</param-name>
    <param-value>fqn</param-value>
    </init-param>
    <init-param>
    <param-name>roleFormat</param-name>
    <param-value>both</param-value>
    </init-param>
    <init-param>
    <param-name>allowGuestLogin</param-name>
    <param-value>false</param-value>
    </init-param>
    <init-param>
    <param-name>impersonate</param-name>
    <param-value>false</param-value>
    </init-param>
    <init-param>
    <param-name>securityFilterProviders</param-name>
    <param-value>
    waffle.servlet.spi.NegotiateSecurityFilterProvider
    waffle.servlet.spi.BasicSecurityFilterProvider
    </param-value>
    </init-param>
    <init-param>
    <param-name>waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols</param-name>
    <param-value>
    Negotiate
    NTLM
    </param-value>
    </init-param>
    <init-param>
    <param-name>waffle.servlet.spi.BasicSecurityFilterProvider/realm</param-name>
    <param-value>Serena Business Manager</param-value>
    </init-param>
    </filter>

    <filter-mapping>
    <filter-name>WaffleIWAFilter</filter-name>
    <url-pattern>/services/rest/iwa</url-pattern>
    </filter-mapping>

    <!-- ========================================================== -->
    <!-- NTLM Principal Filter -->
    <!-- ========================================================== -->
    <filter>
    <filter-name>NtlmPrincipalFilter</filter-name>
    <filter-class>org.eclipse.alf.security.sso.server.federationserver.filter.NtlmPrincipalFilter</filter-class>

    <init-param>
    <param-name>AuthTypeIn</param-name>
    <param-value>ntlm,negotiate</param-value>
    </init-param>
    <init-param>
    <param-name>AuthTypeOut</param-name>
    <param-value>NTLM</param-value>
    </init-param>
    <init-param>
    <param-name>NtlmDomainStrip</param-name>
    <param-value>true</param-value>
    </init-param>
    <init-param>
    <param-name>NtlmDomainAttributeName</param-name>
    <param-value>NtlmPrincipalFilter.NtlmDomain</param-value>
    </init-param>
    </filter>

    <filter-mapping>
    <filter-name>NtlmPrincipalFilter</filter-name>
    <url-pattern>/services/rest/iwa</url-pattern>
    </filter-mapping>


    [1] Using internal passwords for web services, can be a security risk if browser access is protected by another form of authentication such as IWA, LDAP or third party. You would want to ensure that administrators set internal user passwords with a strong password.
    Like
    The reply is currently minimized Show
Your Reply

Recent Tweets