How to debug in IBM worklight application? - ibm-mobilefirst

I have created a sample program but i can't get expected result, so i have debug my application. I want to check/print the URL and Post data to server.
This is my url : mydomain.com/RESTapi/Rest_LoginValidate.php
Post date: UserName : 'pop', UserPwd : 'pop'
The following are the code snippet i used in Worklight.
myRESTAdapter.xml
<?xml version="1.0" encoding="UTF-8"?>
<wl:adapter name="myRESTAdapter"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wl="http://www.ibm.com/mfp/integration"
xmlns:http="http://www.ibm.com/mfp/integration/http">
<displayName>myRESTAdapter</displayName>
<description>myRESTAdapter</description>
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>mydomain.com</domain>
<port>80</port>
<connectionTimeoutInMilliseconds>30000</connectionTimeoutInMilliseconds>
<socketTimeoutInMilliseconds>30000</socketTimeoutInMilliseconds>
<maxConcurrentConnectionsPerNode>50</maxConcurrentConnectionsPerNode>
<!-- Following properties used by adapter's key manager for choosing specific certificate from key store
<sslCertificateAlias></sslCertificateAlias>
<sslCertificatePassword></sslCertificatePassword>
-->
</connectionPolicy>
</connectivity>
<procedure name="getGmapLatLng"/>
</wl:adapter>
myRESTAdapter-impl.js
function getGmapLatLng(UserName,UserPwd) {
var path = '/RESTapi/Rest_LoginValidate.php';
var input = {
method : 'post',
returnedContentType : 'application/json',
path : path,
parameters : {
UserName : 'UserName',
UserPwd : 'UserPwd'
}
};
return WL.Server.invokeHttp(input);
}
Result what i am getting:
{
"UserLogin": {
"ADMIN_FLAG": null,
"ADMIN_FNAME": null,
"ADMIN_ID": null,
"ADMIN_LNAME": null,
"ADMIN_LOCID": null,
"ADMIN_LOCNAME": null,
"ADMIN_MAIL": null,
"ADMIN_SEC_TYPE": null,
"BS_NATURE": null,
"BS_NATURENAME": null,
"RESPONSE": "authentication failed"
},
"isSuccessful": true,
"responseHeaders": {
"Connection": "close",
"Content-Length": "236",
"Content-Type": "text\/html",
"Date": "Thu, 09 Apr 2015 09:25:00 GMT",
"Server": "Apache",
"X-Powered-By": "PleskLin"
},
"responseTime": 583,
"statusCode": 200,
"statusReason": "OK",
"totalTime": 590
}
I am getting result, but i cant able to login successfully (getting authentication failed), so i want to check whether I am passing correct path and post data and want to know why i am getting failure result?

Per the discussion in the chat, you need to change
parameters : {
UserName : 'UserName',
UserPwd : 'UserPwd'
}
To:
parameters : {
UserName : UserName,
UserPwd : UserPwd
}

Related

Question about ASP.NET Core 3 Identity / Identity Server / SPA support for Resource Owner Password Grant Type

As per Authentication and authorization for SPAs, I have created a new SPA with support for API authorization. You can view this on GitHub.
In order to support integration tests, I have added a new client (see appsettings.json) that is allowed the resource owner password grant type:
"SecureSpa.IntegrationTests": {
"Profile": "IdentityServerSPA",
"AllowedGrantTypes": [ "password" ],
"ClientSecrets": [ { "Value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } ],
"AllowedScopes": [ "SecureSpaAPI", "openid", "profile" ]
}
Then within WeatherForecastControllerTests.cs, I attempt to request the token as follows:
var response = await client.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "SecureSpa.IntegrationTests",
ClientSecret = "secret",
Scope = "SecureSpaAPI openid profile",
UserName = "demouser#securespa",
Password = "Pass#word1"
});
When running the test, I've tried many different combinations, however the results are usually the same (unauthorized_client). This is the relevant log output from Identity Server:
IdentityServer4.Endpoints.TokenEndpoint: Debug: Start token request.
IdentityServer4.Validation.ClientSecretValidator: Debug: Start client validation
IdentityServer4.Validation.BasicAuthenticationSecretParser: Debug: Start parsing Basic Authentication secret
IdentityServer4.Validation.PostBodySecretParser: Debug: Start parsing for secret in post body
IdentityServer4.Validation.SecretParser: Debug: Parser found secret: PostBodySecretParser
IdentityServer4.Validation.SecretParser: Debug: Secret id found: SecureSpa.IntegrationTests
IdentityServer4.Stores.ValidatingClientStore: Debug: client configuration validation for client SecureSpa.IntegrationTests succeeded.
IdentityServer4.Validation.ClientSecretValidator: Debug: Public Client - skipping secret validation success
IdentityServer4.Validation.ClientSecretValidator: Debug: Client validation success
IdentityServer4.Events.DefaultEventService: Information: {
"Name": "Client Authentication Success",
"Category": "Authentication",
"EventType": "Success",
"Id": 1010,
"ClientId": "SecureSpa.IntegrationTests",
"AuthenticationMethod": "SharedSecret",
"ActivityId": "0HLPN4PPDDMCJ",
"TimeStamp": "2019-09-12T02:10:57Z",
"ProcessId": 28948,
"LocalIpAddress": "unknown",
"RemoteIpAddress": "unknown"
}
IdentityServer4.Validation.TokenRequestValidator: Debug: Start token request validation
IdentityServer4.Validation.TokenRequestValidator: Debug: Start resource owner password token request validation
IdentityServer4.Validation.TokenRequestValidator: Error: Client not authorized for resource owner flow, check the AllowedGrantTypes setting{ client_id = SecureSpa.IntegrationTests }, details: {
"ClientId": "SecureSpa.IntegrationTests",
"ClientName": "SecureSpa.IntegrationTests",
"GrantType": "password",
"Raw": {
"grant_type": "password",
"username": "demouser#securespa",
"password": "***REDACTED***",
"scope": "SecureSpaAPI",
"client_id": "SecureSpa.IntegrationTests",
"client_secret": "***REDACTED***"
}
}
IdentityServer4.Events.DefaultEventService: Information: {
"Name": "Token Issued Failure",
"Category": "Token",
"EventType": "Failure",
"Id": 2001,
"ClientId": "SecureSpa.IntegrationTests",
"ClientName": "SecureSpa.IntegrationTests",
"Endpoint": "Token",
"GrantType": "password",
"Error": "unauthorized_client",
"ActivityId": "0HLPN4PPDDMCJ",
"TimeStamp": "2019-09-12T02:10:57Z",
"ProcessId": 28948,
"LocalIpAddress": "unknown",
"RemoteIpAddress": "unknown"
}
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 212.96790000000001ms 400 application/json; charset=UTF-8
Is this approach supported? If not, is there an alternative approach that can be used to get the token in order to write integration tests? I'm planning to set up test users along with the test client so that I can test lots of different behaviours.
I continued working on this issue and found that the allowed grant type of password was not being added when the profile is set to IdentityServerSPA. I couldn't see a way to add a client without a profile via appsettings, so I removed the configuration from appsettings and created the clients using this approach:
services.AddIdentityServer()
//.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options =>
{
options.Clients.AddIdentityServerSPA("SecureSpa", builder =>
{
builder.WithRedirectUri("https://localhost:44307/authentication/login-callback");
builder.WithLogoutRedirectUri("https://localhost:44307/authentication/logout-callback");
});
options.Clients.Add(new Client
{
ClientId = "SecureSpa.IntegrationTests",
AllowedGrantTypes = { GrantType.ResourceOwnerPassword },
ClientSecrets = { new Secret("secret".Sha256()) },
AllowedScopes = { "SecureSpaAPI", "openid", "profile" }
});
});
With that in place my tests now run. You can see the final solution here; https://github.com/JasonGT/SecureSpa/.
Everything works fine, however there seems to be a bug (or feature limitation) within DefaultClientRequestParametersProvider. See the 'GetClientParameters' method - if the specified client does not have an associated profile, an InvalidOperationException is thrown.
Let me know if you need more information.
Just for reference' sake: the code above did not work as-is on my end, it broke the SPA sign-in with a redirect_uri invalid exception.
I had to remove the base url, and then it worked:
builder.WithRedirectUri("/authentication/login-callback");
builder.WithLogoutRedirectUri("/authentication/logout-callback");

Cognito custom claims missing with Amplify but not with Appsync Console

I have the following resolver, allowing me to retrieve information about the current user company (companyId is added as a custom field on the cognito user pool). The field on cognito is set to mutable.
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key": {
"id" : $util.dynamodb.toDynamoDBJson($context.identity.claims.get("custom:companyId"))
}
}
This works fine when using the AWS AppSync interface (after login in) as the logs show:
{
"errors": [],
"mappingTemplateType": "Request Mapping",
"path": "[getMyClientCompany]",
"resolverArn": "arn:aws:appsync:eu-west-1:261378271140:apis/rue25cac6jc6vfbhvu32sjafqy/types/Query/fields/getMyClientCompany",
"transformedTemplate": "{\n \"version\" : \"2017-02-28\",\n \"operation\" : \"GetItem\",\n \"key\": {\n \"id\" : {\"S\":\"0c1c81db-a771-4856-9a30-d11bf8e3cab1\"}\n }\n}",
"context": {
"arguments": {},
"source": null,
"result": null,
"error": null,
"outErrors": []
},
"fieldInError": false
}
But doesn't work when the code comes from Amplify-js:
{
"errors": [],
"mappingTemplateType": "Request Mapping",
"path": "[getMyClientCompany]",
"resolverArn": "arn:aws:appsync:eu-west-1:261378271140:apis/rue25cac6jc6vfbhvu32sjafqy/types/Query/fields/getMyClientCompany",
"transformedTemplate": "{\n \"version\" : \"2017-02-28\",\n \"operation\" : \"GetItem\",\n \"key\": {\n \"id\" : {\"NULL\":null}\n }\n}",
"context": {
"arguments": {},
"source": null,
"result": null,
"error": null,
"outErrors": []
},
"fieldInError": false
}
The key that should be "custom:companyId" is "NULL" now
I imagine the issue is either with Amplify (version 0.4.8) or with the cognito user resolver for some reason
Any idea what could be going on?
There are two JWT tokens Cognito may utilize. ID and Access. ID token seems to contain those custom claims.
From Amplify you tweak the Authorization header to use ID token vs Access token.
Here's the code, put it in AWS Amplify configuration:
API: {
graphql_endpoint: 'https://****.appsync-api.***.amazonaws.com/graphql',
graphql_region: '***',
graphql_authenticationType: 'AMAZON_COGNITO_USER_POOLS',
graphql_headers: async () => {
try {
const token = (await Auth.currentSession()).idToken.jwtToken;
return { Authorization: token }
}
catch (e) {
console.error(e);
return {};
// Potentially you can retrieve it from local storage
}
}
}
Note, there seem to be several different keys to configure Amplify keys:
for example, aws_appsync_graphqlEndpoint vs API { graphql_endpoint }, I used the latter.

camunda Cannot find task with id task is null

I'm beginner in Camunda. I would like to complete a task.
So I start an instance by calling :
http://localhost:8080/engine-rest/process-definition/key/approve-loan/submit-form
via Postman and POST request with following data :
{
"variables": {
"customerId": {"value":"Niall","type":"String"},
"amount":{"value":"100","type":"String"}
}
}
and Content-Type : application/json
I have the following output :
{
"links": [
{
"method": "GET",
"href": "http://localhost:8080/engine-rest/process-instance/3f219a2a-138e-11e7-b49e-104a7ddf1366",
"rel": "self"
}
],
"id": "3f219a2a-138e-11e7-b49e-104a7ddf1366",
"definitionId": "approve-loan:2:8cd1ab3c-1303-11e7-b49e-104a7ddf1366",
"businessKey": null,
"caseInstanceId": null,
"ended": false,
"suspended": false,
"tenantId": null
}
I looked in the camunda blog and I found I can complete the task instance by calling (POST request):
http://localhost:8080/engine-rest/task/3f219a2a-138e-11e7-b49e-104a7ddf1366/complete
The problem is that's not working since I have the following response :
{
"type": "RestException",
"message": "Cannot complete task 3f219a2a-138e-11e7-b49e-104a7ddf1366: Cannot find task with id 3f219a2a-138e-11e7-b49e-104a7ddf1366: task is null"
}
and this exception in tomcat console :
Caused by: org.camunda.bpm.engine.exception.NullValueException: Cannot find task with id 3f219a2a-138e-11e7-b49e-104a7ddf1366: task is null
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.camunda.bpm.engine.impl.util.EnsureUtil.generateException(EnsureUtil.java:334)
at org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull(EnsureUtil.java:49)
at org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull(EnsureUtil.java:44)
at org.camunda.bpm.engine.impl.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:47)
at org.camunda.bpm.engine.impl.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:30)
at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:104)
at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.camunda.bpm.engine.impl.TaskServiceImpl.complete(TaskServiceImpl.java:170)
at org.camunda.bpm.engine.rest.sub.task.impl.TaskResourceImpl.complete(TaskResourceImpl.java:95)
... 37 more
I have called http://localhost:8080/engine-rest/task/?processInstanceId=3f219a2a-138e-11e7-b49e-104a7ddf1366
to get properties and the response is
[
{
"id": "3f220f63-138e-11e7-b49e-104a7ddf1366",
"name": "Approve Loan",
"assignee": "john",
"created": "2017-03-28T10:12:12",
"due": null,
"followUp": null,
"delegationState": null,
"description": null,
"executionId": "3f219a2a-138e-11e7-b49e-104a7ddf1366",
"owner": null,
"parentTaskId": null,
"priority": 50,
"processDefinitionId": "approve-loan:2:8cd1ab3c-1303-11e7-b49e-104a7ddf1366",
"processInstanceId": "3f219a2a-138e-11e7-b49e-104a7ddf1366",
"taskDefinitionKey": "UserTask_11fud4o",
"caseExecutionId": null,
"caseInstanceId": null,
"caseDefinitionId": null,
"suspended": false,
"formKey": "embedded:app:forms/approve-loan.html",
"tenantId": null
}
]
I have used id and executionId but I still get the error.
Any help please ?
Thanks to #Zelldon :
The working URL is http://localhost:8080/engine-rest/task/3f220f63-138e-11e7-b49e-104a7ddf1366/complete
I just have to take the id from the response got after the call of http://localhost:8080/engine-rest/task/?processInstanceId=3f219a2a-138e-11e7-b49e-104a7ddf1366
Please mark it as resolved since I can't.

Invoking http adapter procedure failure

I'm trying to send some values to a web server and it is going to respond with true or false using http adapter in ibm mobilefirst. When i invoke the procedure from the environment, i got this error:
{
"errors": [
"Runtime: Http request failed: java.net.UnknownHostException: mfpreader.comze.com\/"
],
"info": [
],
"isSuccessful": false,
"warnings": [
]
}
Here is the link i'm using:
http://mfpreader.comze.com/login.php?username=kevin&password=pass
The server is working.
LoginAdapter.xml
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>https</protocol>
<domain>mfpreader.comze.com/</domain>
<port>443</port>
<procedure name="getVerify"/>
LoginAdapter-impl.js
function getVerify(pName) {
var input = {
method : 'get',
returnedContentType : 'json',
path : '/login.php',
parameters : {
'username' : pName,
'password' : 'pass' // hard-coded
}
};
return WL.Server.invokeHttp(input);
}
Can i have some help please. Thanks.
I think your issue is that you have a surplus / in your domain name:
<domain>mfpreader.comze.com/</domain>
This is a domain name, not a URL. You need to specify only the hostname of the server you are trying to reach:
<domain>mfpreader.comze.com</domain>
connect website using http port 80 .on the other hand return returnedContentType : 'plain' .
LoginAdapter.xml
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>mfpreader.comze.com</domain>
<port>80</port>
<procedure name="getVerify"/>
LoginAdapter-impl.js
function getVerify(pName) {
var input = {
method : 'get',
returnedContentType : 'plain',
path : '/login.php',
parameters : {
'username' : pName,
'password' : 'pass' // hard-coded
}
};
return WL.Server.invokeHttp(input);
}
invocation result:
{
"errors": [
],
"info": [
],
"isSuccessful": true,
"responseHeaders": {
"Connection": "close",
"Content-Length": "748",
"Content-Type": "text\/html",
"Date": "Fri, 19 Feb 2016 11:56:31 GMT",
"Server": "Apache",
"X-Powered-By": "PHP\/5.2.17"
},
"responseTime": 563,
"statusCode": 200,
"statusReason": "OK",
"text": "<br><table border='1' cellpadding='2' bgcolor='#FFFFDF' bordercolor='#E8B900' align='center'><tr><td><font face='Arial' size='1' color='#000000'><b>PHP Error Message<\/b><\/font><\/td><\/tr><\/table><br \/>\n<b>Warning<\/b>: json_encode() expects exactly 1 parameter, 2 given in <b>\/home\/a1974455\/public_html\/login.php<\/b> on line <b>72<\/b><br \/>\n<br><table border='1' cellpadding='2' bgcolor='#FFFFDF' bordercolor='#E8B900' align='center'><tr><td><div align='center'><a href='http:\/\/www.000webhost.com\/'><font face='Arial' size='1' color='#000000'>Free Web Hosting<\/font><\/a><\/div><\/td><\/tr><\/table> \n<!-- Hosting24 Analytics Code -->\n<script type=\"text\/javascript\" src=\"http:\/\/stats.hosting24.com\/count.php\"><\/script>\n<!-- End Of Analytics Code -->",
"totalTime": 578,
"warnings": [
]
}
The website does not work.
When you pointed to it, you're using http, but in the XML you're using https. And when trying to access the website with the https protocol, it is not loading.

Calling Worklight adapter from external app

I have deployed the adapter on Worklight server and there is some requirement where I am calling worklight adapter from outside as a rest serverice , it is working fine and returning data as required but instead of giving json output it is giving HTML
<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>Invoke Procedure Result</title><script src="/secure/console/js/jquery-1.6.min.js"></script><style> textarea { width: 100%; } .textwrapper { margin: 5px 0; padding: 3px; }</style></head><body onload="attachEvent();"><div><span id="invRes">Invocation Result of procedure: 'Authentication' from the Worklight Server</span>: </div><div id="target"><textarea rows="20">{
"RESPONSE": {
"USER_ID": "292265"
},
"errors": [
],
"info": [
],
"isSuccessful": true,
"responseHeaders": {
"Content-Length": "1195",
"Content-Type": "text\/xml;charset=ISO-8859-1",
"Date": "Thu, 21 Nov 2013 10:10:13 GMT",
"Server": "Oracle GlassFish Server 3.1.2.2",
"X-Powered-By": "Servlet\/3.0 JSP\/2.2 (Oracle GlassFish Server 3.1.2.2 Java\/Oracle Corporation\/1.7)"
},
"responseTime": 4234,
"statusCode": 200,
"statusReason": "OK",
"totalTime": 4235,
"warnings": [
]
}</textarea></div><script>function attachEvent() {$('#target').ajaxError(function(e, xhr, ajaxOptions, thrownError){$(this).text("Error: Please ensure that the XML input and XSL transformation are valid and try again.");});}function run_xslt() {var xml = $('#originalXML').val();var xsl = $('#originalXSL').val();$.post('/secure/dev/xslt',{'xml':xml,'xsl':xsl},function(data, textStatus, XMLHttpRequest){$('#target').empty();json = $("<textarea></textarea>");json.attr("rows",25);json.text(data);$('#target').append(json);$('#invRes').text('Result of Local XSL Transformation');},'text');}</script></body></html>
in code I am again parsing it from HTML and storing json into string. Then only i can use it. This is the url given below for calling adapter externally as per worklight docs.
http://WorklightServer.com/secure/dev/invoke?adapter=Reports&procedure=Authentication&parameters=%5B%5D
remove /dev/ component from the URL, it is for development ease purposes only. without it you'll get your JSON.
I had the same issue and after reading Anton's answers I set the "dataType" of the Ajax call to "text" and then edit the response to remove the /*-secure- and */ and then parsed the string to get the JSON "JSON.parse(theString)"
$.ajax({
type: 'POST',
url: ajaxURL,
async: true,
cache: true,
timeout: 5,
dataType: "text",
success: function(data){
data = data.replace("/*-secure-","");
data = data.replace("*/","");
var dataJSON = JSON.parse(data);
//Do success
},
error: function(data, statusCode){
//Do error
}
});