SustainsSys SAML form data duplicate key issue - saml-2.0

I am trying to submit the form data on SustainSys Stub IDP page as part of automation test suite that is simulating SAML login without involving the browser.
I am submitting the form data POST request but it appears that the duplicate keys required by the form are not being submitted in the form data.
Request looks like this:
request({
method: 'POST',
url: 'https://stubidp.sustainsys.com/{id}',
form: true,
body: {
"AssertionModel.AttributeStatements.Index": "0",
"AssertionModel.AttributeStatements[0].Type": "urn:oid:2.5.4.10",
"AssertionModel.AttributeStatements[0].Value": "Test 123",
"AssertionModel.AttributeStatements.Index": "1",
"AssertionModel.AttributeStatements[1].Type": "https://some-url.com",
"AssertionModel.AttributeStatements[1].Value": "001",
"AssertionModel.AttributeStatements.Index": "2",
"AssertionModel.AttributeStatements[2].Type": "https://some-url.com",
"AssertionModel.AttributeStatements[2].Value": "Open",
"AssertionModel.AttributeStatements.Index": "16",
"AssertionModel.AttributeStatements[16].Type": "urn:oid:2.5.4.4",
"AssertionModel.AttributeStatements[16].Value": 'Admin-Smith'
}
})
The issue is with the "AssertionModel.AttributeStatements.Index" properties as only the last one with value 16 is being sent by the JS Library I am using for the request. As a result the SAML response being returned isn't correct. How can these properties be sent so they are parsed correctly by the endpoint?

Looks like "AssertionModel.AttributeStatements.Index" properties are not actually required. the request works without these.

Related

How to get User Access Token claims for Facebook registered app

I am used to working with Azure Active Directory. I know that if I register an app, I can use MSALs library in React (which uses OIDC in the background) to get a JWT Token (I actually get 2, an ID and an Access Token, but that is beyond the scope of this question). I can then make a call from my front end to my back end API, and send that token through as authentication. In the backend, I check the signature, and also check that the app of the token is the app that I registered, and also that the token is generated for use 'X'. So with that single token I can protect my backend API and make sure that the frontend call is legitimately coming from the SPA (unless the token gets stolen), and that the user 'X' is the one whose session is active for the given API call.
Now, for a personal project, I am trying to work with Facebook as an identity provider. I registered my app in facebook, and in my freshly created react project I have:
<React.StrictMode>
<FacebookLogin
appId="<App ID Here>"
autoLoad={false}
fields="name,email,picture"
callback={responseFacebook}
/>
<App />
</React.StrictMode>
and
const responseFacebook = (response) => {
console.log(response);
}
Now, when I click the button, I see the following in the console:
{
"name": "<My Name Here>",
"email": "<My Mail Here>",
"picture": "<Picture Data Here>",
"id": "<ID Here>",
"accessToken": "EAAJlEXBfRWgBAGHTP0ZAgRttMSMZzAxWM4B6aAZBL7FlGSWgZBITj9HXb2mZAVuoyIc1V43StjYwuwcsSTZBEd4aPK6iGwbNGRvN7o5PH3ZAOymGxtb5W8k2BYYdAW5w1frXt8JeEvJI3SCoOsJqMVHm9mo5N7NpSZBKs74wqu8LvgQbqqYfvialeSP5LwtUMMS51pMsN5Kwv7aWPud0",
"userID": "<User ID Here>",
"expiresIn": 6488,
"signedRequest": "<A Bunch of Gibberish>",
"graphDomain": "facebook",
"data_access_expiration_time": 1677528712
}
Now, about the access token, that is no JWT and I dont know how to use it for authenticating against my OWN backend API. I know I can use that token to make requests to facebook GraphAPI and get more info about the user (in this case, me). But, when I make a request to my backend, and I send that token, I have no clue how to verify its a legitimate token, meaning:
Verify its signed by facebook
Verify the APP ID is the one im looking for
Verify for which user was the token generated
In good old JWT, I can simply check the claims, but I have no idea what this is and how to prove to a backend server, or any third party for that matter, that the token was generated by 'X' user interacting with 'Y' app registered on facebook
Well, as per #CBroe's suggestion, I used the debug token Graph endpoint to retrieve info about the token (Doc https://developers.facebook.com/docs/graph-api/reference/v15.0/debug_token).
So in the front end, I get the info shown in the question, and I need to pass that info to a backend API, as well as proof of said info legitimacy. So, in pseudocode:
// Frontend
body = {
"name": "<My Name Here>",
"email": "<My Mail Here>",
"picture": "<Picture Data Here>",
"id": "<ID Here>",
"accessToken": "EAAJlEXBfRWgBAGHTP0ZAgRttMSMZz...",
"userID": "<User ID Here>",
"expiresIn": 6488,
"signedRequest": "<A Bunch of Gibberish>",
"graphDomain": "facebook",
"data_access_expiration_time": 1677528712
};
RestClient.call("myapiurl/myendpoint", "HTTP_METHOD", body=body);
and
// Backend
function checkValidity(info) {
version = "v15.0"
token = info.accessToken;
endpointURL = "https://graph.facebook.com/${version}/debug_token?input_token=${token}";
headers = { "Authorization": "Bearer ${token}" };
response = RestClient.call(endpointURL, "GET", headers=headers);
// Note that the token is sent twice, once for Auth purposes, and another time as payload for the debug endpoint
/*
The response will look like:
{
"data": {
"app_id": "<APP ID>",
"type": "USER",
"application": "<APP Name>",
"data_access_expires_at": 1677601862,
"expires_at": 1669831200,
"is_valid": true,
"scopes": [
"email",
"public_profile"
],
"user_id": "<USER ID>"
}
}
*/
if (response.data.app_id == "<MY APP ID>" && response.data.user_id == info.userID) {
return true;
} else {
return false;
}
}
app.post('/myendpoint', function(req, res) {
checkValidity(req.body);
res.send('some result');
});
This way we can be sure that the token is valid (as if it wasn't, the facebook endpoint would have returned an error. Also, we can confirm the token was generated by userID for appID. In your backend data system you need to use the userID as your main reference, because its the only guaranteed value to have to map that user's activity in that appID (unless the user allows the app to read the email).
Note that the userID is different for each user-app pair, so if you want data such as the user email, you need to use the token to hit facebook's /user endpoint with that userID to get the info you need.
You should not trust the email field sent in the body because, since the AppID is public as its dealt with in the frontend, someone could make up a mock frontend and login with their own account (therefore generating a valid token with its matching userID) and forge the rest of the fields in the body.
This assumes the token has not been stolen (as with any bearer token solution), and that the user is careful and aware of where he/she is signing into, (as a malicious phishing clone frontend could trick the user into SSOing into a fake site).

How to create a case in a Salesforce Account using REST API and python Script

I need some help. I need to create a case in a Account with all the details basically, all the fields, using REST API but it I am not able to figure out, how to insert a record for creating a case.
Could you please guide me, how to create a case using REST API in Salesforce?
Do you use a library such as https://pypi.org/project/simple-salesforce/0.3/ or do you need to craft the REST messages manually?
You'd need to do it in 2 calls, login first (unless you have session id already) and then
POST to
https://yourinstance.my.salesforce.com/services/data/v48.0/sobjects/Case
with header
Authorization Bearer <session id goes here, sometimes called "access token" too>
and body
{
"Subject": "Hello world",
"Description": "Lorem ipsum dolor sit amet...",
"Origin":"Web",
"AccountId" :"0010g00001mbqU4"
}
should work like a charm (pass an account id value right for your org and you might have more fields to fill in).
So now "only" how to log in. That's a bigger topic and depends if it's a backend thing or you'll have a human interacting with it, maybe logging in to SF and then coming back to your org. There's bit of reading on that (simpler if you'd use SOAP API to log in)
For example this would work if I didn't redact all sensitive stuff
POST to
https://login.salesforce.com/services/oauth2/token
with header
Content-Type application/x-www-form-urlencoded
and body
grant_type=password
&client_id=(ask your admin for "connected app")
&client_secret=(ask your admin for "connected app")
&username=redacted%40example.com
&password=redacted
Should return
{
"access_token": "<session id here, use it as Authorization header in next calls>",
"instance_url": "<use this as base url of all next calls>",
"id": "<call GET to this (with the Auth header) to learn more about user",
"token_type": "Bearer",
"issued_at": "1593684589157",
"signature": "redacted"
}
Again - don't do it all by hand if you can, use one of Python libraries for Salesforce.
from simple_salesforce import Salesforce
sf = Salesforce(
username='user name of salesforce account',
password='password',
security_token='token')
Sample data
data ={
"Name" : "ABCD",
"Contact" : "123456789",
"Description":"Radio has damaged because of handling."
}
create record
x = sf.Account.create(data)

How to update the users birthday

I want to update the birthday of a user using the patch request.
Updating other properties works as expected but the moment the birthday property is included, the following error returned:
The request is currently not supported on the targeted entity set
I already tried to update the user to be sure the permissions are fine.
Application permissions are used.
This PATCH request to /V1.0/users/{id} works:
{
"givenName": "Fridas"
}
Passing this request body however:
{
"givenName":"Fridas",
"birthday" : "2014-01-01T00:00:00Z
}
throws an error
{
"error":
{
"code":"BadRequest",
"message":"The request is currently not supported on the targeted entity set",
"innerError":
{
"request-id":"5f0d36d1-0bff-437b-9dc8-5579a7ec6e72",
"date":"2019-08-13T15:27:40"
}
}
}
When I update the birthday separately, I get a 500 error. Print screens below. Updating the user id works fine, birthday does not.
Same user id is used in the request.
I'm not sure why this happens, but a workaround, albeit an annoying one, is to update birthday separately from other attributes.
E.g.
PATCH https://graph.microsoft.com/v1.0/users/userid
{
"birthday" : "2014-01-01T00:00:00Z"
}
Here is a screenshot from MS Graph Explorer:
In fact, this is a limitation in the current system.
User is a composite type. Under the covers some properties in user are mastered by different services, and we currently don't support updates across multiple services.
"birthday" is not mastered by Azure AD. So we can't update it with other properties mastered by Azure AD in the same call.
It is strongly recommended that you update this property separately. I can update it from my side. So you need a backend engineer to track this request for you.
This seems to affect more than Birthday.
Skills[] and Responsibilities[] are also returning 500 Internal Server Error when using PATCH request via REST API with:
{"skills": ["TESTING", "ANOTHER SKILL"]}
Same happens via the GraphServiceClient - except the result is:
Failed to call the Web Api: InternalServerError
Content: {
"error": {"code": "-1, Microsoft.Office.Server.Directory.DirectoryObjectUnauthorizedAccessException",
"message": "Attempted to perform an unauthorized operation.",
"innerError": {
"request-id": "1c2ccc54-0a0c-468f-a18c-6bdfbad4077d",
"date": "2019-08-28T13:23:55"
}}}
These requests work on the Graph Explorer page, but not via calls to the API.

Where to find the onPremissesImmutableId?

I´m writing an little application to create new user on an Azure AD.
Even following all the instructions in Create User Reference I allways get an Http Error 400 (Bad Request).
The only thing I´m not providing is an attribute named onPremissesImmutableId. Assuming I must provide it, problem is I don't know where to find such a value.
This is the Json I'm posting:
{
"accountEnabled": true,
"displayName": "Name Surname",
"mailNickname": "Surname",
"userPrincipalName": "name.surname#XXXX.onmicrosoft.com",
"passwordProfile" : {
"forceChangePasswordNextSignIn": false,
"password": "p#ssw0#D"
}
}
Any ideas?
TIA
Just after I posted the question I had the idea to review the password policy active on my AD tenant and I found out that it was the problem. So I just had to set a new password to match the policy and everything worked just fine.

How to Check $http.post() query result using POSTMAN

I have $http.post request and it works fine.
$http.post("api/orders/", $scope.order).success(function(data) {
}
Where
$scope.order = {
"order_id": "14",
"user_id": "10",
"amount":"400"
};
How can I check the same request using postman?
If you are running the service locally, set the url to :
http://localhost/api/orders
If its not running locally, change localhost to your server name
Then set the method to POST
click on "form data" which allows you to submit key value pairs
then enter your keys and values as per your scope.order object

Resources