Can I customize WSO2 APIM token response JSON attributes? - oauth

By default, WSO2 returns a JSON when you send a token request to /token that looks like this:
{
"access_token": "b73fc57e-83cc-3550-87ce-d015611da33a",
"scope": "scope1 scope2",
"token_type": "Bearer",
"expires_in": 1336
}
What i want is to fully customize the JSON output, being able to add and remove attributes, to get something like this instead:
{
"access_token": "b73fc57e-83cc-3550-87ce-d015611da33a",
"scope": "scope1 scope2",
"day": "monday",
"name": "mark"
}
I have implemented a custom grant that gets some data from another service and I want the JSON to include it as part of the response. I am very new to WSO2 and all I have found about this is this other question Is it possible to modify WSO2 token response?
The proposed solution there is to implement a new TokenResponseTypeHandler, but as far as I've seen that class only sets the variables in a OAuthAuthzReqMessageContext object type, which are the ones that appear later in the JSON attributes (e.g. .setScope() sets the value for the "scope" attribute in the json), but no actual JSON formatting is done there and I can't find any information about who does it or where this OAuthAuthzReqMessageContext is being extracted after these handlers.
Is it possible to do this? If so, how can I do it and where? I am using WSO2 API Manager 3.0
Thank you

Related

Create SharePoint list item with lookup field with Microsoft Graph

I am trying to create list items with Microsoft Graph's new SharePoint endpoint. My URL is as follows:
https://graph.microsoft.com/beta/sites/{site-id}/lists/{list-id}/items
Calling this URL with POST, and a body like this:
{
"fields": {
"Title": "test",
}
}
.. works! But if I include a lookup field, the lookup field is always empty. I have tried with
"{columnName}": "id",
"{columnName}": "id;#value",
"{columnName}": {
"#odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference", //and others like this
"Id": "id",
"Value": "value",
}
"{columnName}": "value",
"{columnName}Id": "id",
None of these seems to work. Some give an error like "The request is malformed or incorrect.", others go through, but doesn't include the lookup field.
The documentation for this is scarce (if any), and I have found very little information on google (apart from someone asking the same question with no answers). Anyone that got this to work yet? Is it even possible?
I have got this to work with people fields where the multiple selection option was DISABLED. So if you have a person field which allows one person only, the following works.
"{columnName}LookupId": id
Additionally, the id still needs to be the SP ID and not the graph user GUID. This ID changes from site to site.
You need to add a lookup column in the following format
"Office": "London",
"OfficeLookupId", "16"
Where Office is the name of the column

OData PUT to replace collection property

Using the OData standard is it possible to replace collection by sending a new collection?
Scenario:
The person object contains a list Address object. I would want to replace the Address collection with a new collection.
PUT Persons(1)/Addresses
[{"city": "X", "country": "US"}, {"city": "Y", "country": "US"}]
This is not possible out of the box (at least for ODATAv3), as the default routing template does not expect segments after the key portion.
But you should be able to add an ODATA Action that would do what you want to achieve. Your action definition could then look similar to this:
var action = builder.Entity<Person>()
.Action("Addresses")
.Returns<bool>();
action.Parameter<Collection<CityCountryPair>>("data");
The type CityCountryPair would be a regular DTO containing your properties you want to change. Make sure this type is also registered as an EntitySet in Odata or use a plain map/dictionary with only primitive types.
The actual call to the ODATA action would then look similar to this:
POST http://www.example.com/api/YourEndpoint/Persons(42)/Addresses
Content-Type: application/json
{
"data" :
[
{ "city" : "Berne" , "country": "CH" },
{ "city" : "Y" , "country": "CH" }
]
}
If you want to send more complex data types you can still resort to a customer JSON Deserialiser and override the default one or use a custom model binder after all.

Zapier multi step triggers and passing variables

I am getting stuck creating my own app to use within Zapier. It is for an unsupported CRM
https://www.brightpearl.com/developer/latest/
I have been able to authenticate and create a test trigger - a simple call to retrive information about one product ID where the ID is provided in the request URL manually.
Example Use Case
Using an Email sent to a GMail account, search for a customerand add the body of the email as a note to the customer.
I can search using Zapier->Searches to retrieve a result.
The Brightpearl API search returns an ID for any matched contacts.
https://www.brightpearl.com/support/documentation/resource-search
The ID can be accessed in the json response
{
response: {
results: [
[
4,
"admin#email.com",
"Primary",
"Admin"
]
]
},
reference: {}
}
The ID is required to add the note later
How do I store the ID to use in the Action later?
How do I chain the events together so that the Action is called after the ID is captured?
I have gone through the Zapier documentation and cannot find example code which does this.
The trigger that exposes the ID in the API response (in this case, the Brightpearl search result) can be mapped to a subsequent action. You don't store data in Zapier - you just pass it between actions.
Zapier's multi-step interface lets you append actions which can accept any data returned from the previous step.

What 'sensitive information' could be disclosed when setting JsonRequestBehavior to AllowGet

I've been getting the same old error every time I test a new URL from my browser's address bar when I'm returning Json (using the built-in MVC JsonResult helper):
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
Rather than grunt in acknowledgement and fire up Fiddler to do a post request, this time, I'm wondering exactly what it is that a GET request exposes that a POST request doesn't?
in your return use the following:
return this.Json("you result", JsonRequestBehavior.AllowGet);
Say your website has a GetUser web method:
http://www.example.com/User/GetUser/32
which returns a JSON response:
{ "Name": "John Doe" }
If this method accepts only POST requests, then the content will only be returned to the browser if an AJAX request is made to http://www.example.com/User/GetUser/32 using the POST method. Note that unless you have implemented CORS, the browser will protect the data from other domains making this request to yours.
However, if you allowed GET requests then as well as making an AJAX request similar to the above with GET instead of POST, a malicious user could include your JSON in the context of their own site by using a script tag in the HTML. e.g. on www.evil.com:
<script src="http://www.example.com/User/GetUser/32"></script>
This JavaScript should be useless to www.evil.com because there should be no way of reading the object returned by your web method. However, due to bugs in old versions of browsers (e.g. Firefox 3), it is possible for JavaScript prototype objects to be redefined and make it possible for www.evil.com to read your data returned by your method. This is known as JSON Hijacking.
See this post for some methods of preventing this. However, it is not a known problem with the later versions of modern browsers (Firefox, Chrome, IE).
By default, the ASP.NET MVC framework does not allow you to respond to
a GET request with a JSON payload as there is a chance a malicious user can gain access to the payload through a process known as JSON Hijacking. You do not want to return sensitive information using JSON in a GET request.
If you need to send JSON in response to a GET, and aren't exposing sensitive data, you can explicitly allow the behavior by passing JsonRequestBehavior.AllowGet as a second parameter to the Json
method.
Such as
[HttpGet] //No need to decorate, as by default it will be GET
public JsonResult GetMyData(){
var myResultDataObject = buildMyData(); // build, but keep controller thin
// delegating buildMyData to builder/Query Builder using CQRS makes easy :)
return Json(myResultDataObject, JsonRequestBehavior.AllowGet);
}
Here is an interesting article from Phil Haack JSON Hijacking about why not to use Json with GET method
When we want to return a json object to client from MVC application, we should explicit specify JsonRequestBehavior.AllowGet when returning an object. As a result, I return json data as below to overcome the issue:
return Json(yourObjectData, JsonRequestBehavior.AllowGet);
You must be use JsonRequestBehavior.AllowGet for Json Response like this :
return Json(YourObject, JsonRequestBehavior.AllowGet);
return Json("Success", JsonRequestBehavior.AllowGet)

Can i wrap the OAuth 2.0 results in custom objects?

I see samples where OAuth is returned as json as such:
{
"access_token" : "ya29.AHES6ZSHB-aaa",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "1/LkGHrqtU"
"scope" : "ALL"
}
My question is, is there any harm in wrapping up this in a custom object?
ie:the diff is the strong object name/wrapper being included in the return json. I just want to know if this would still be considered as a 'standard' OAuth provider.
{"OAuthResult":{"access_token":"abc","refresh_token":"123","token_type":"Bearer","expires_in":"3900"}}
I have read the spec and see that you MUST include a GET for obtaining the token, but i don't recall the return object being specifically spec'd?
thanks a lot.
From the current (v2-31) OAuth2 draft, section 5.1:
The parameters are included in the entity body of the HTTP response
using the "application/json" media type as defined by [RFC4627]. The
parameters are serialized into a JSON structure by adding each parameter
at the highest structure level. Parameter names and string values are
included as JSON strings. Numerical values are included
as JSON numbers. The order of parameters does not matter and can vary.
So you will NOT be 'standard' with such a response.

Resources