Is there a way to get the username (or Fullname or anything of off SystemUser) in a regular C# console application?
If I do a WhoAmIRequest and then use the UserId to Retrieve "SystemUserEntity" from OrganizationService, it says that there's no entity with the name 'SystemUser'.
If I try to make a GET request with that UserId to the OData REST endpoint (for example: http://localhost:8081/TestOrg/XRMServices/2011/OrganizationData.svc/SystemUserSet(guid'58a30c1a-3730-e511-80c8-080027c078bd'), I keep getting 401 forbidden, although if I simply paste that link into my browser, I get all of the info I need. As far as I understand, that is because I have authentification when using my browser.
So, another possible question would be "how to get correct authentification in a C# Console Application to talk to the OData REST endpoint".
Retrieving the fullname once you have the user id works like this:
// guid userId = ...
var username = service.Retrieve("systemuser", userId, new ColumnSet("fullname")).GetAttributeValue<string>("fullname");
Caveat being, you have to use the logical names (all lowercase) instead of the schema (capitalized) name, i.e. systemuser instead of SystemUser
Related
Before adding, yes it works when I give the entire url like http://localhost:8080/onedrive/oauth2/success/1 in the list of uri in azure uris. I am using code flow to authroize these tokens.
But as per the docs, it should work with me just mentioning the domain name there, like http://localhost:8080. Which it doesn't.
I want to do something like send the user id along with every request for me to keep track of which user I should link this accees token to, and have no idea to do so, if this issue is there. My current application logic is, when my application sends the user details and calls my spring API, I want to handle all these transfer of tokens in the server side, so I want to transfer this userId as my path variable. How do I go about doing this? Has anyone done this, can they explain to me any other different solution?
You can't add custom details to OAuth redirects and it is best practice to always register the full redirect uri.
In terms of tracking the user, after login the token has a user id and you can also get fields such as user name and email - so both the UI and API will know which user each token is for. I can provide further details on mechanics if needed.
The user id in a token is often a generated value, whereas the user id you want to use in API path segments is maybe a user id from your app's back end database - if so you will need to map between token details and database details.
If you provide redirect uri as http://localhost:8080/ then it means you are handling the api response in
/
endpoint and not
/onedrive/oauth2/success/1
To get to know the user to whom you are linking, few ideas which you can use are
1) Use security to obtain the logged in user credentials (Ex: Principal if you're using Spring security in java)
2) After successful authentication, use the user id you have and send one more request to backend and store it database with userid as a key
I want to simulate the password reset service for service now users from an external application and I have installed Password Reset - Orchestration Add-on plugin on my servicenow developer instance. Along with this I can see a list of Pwd Reset APIs on my REST explorer (e.g pwd_init, pwd_verify, etc). I went through the documentation available on this documentation page but I'm at a loss to understand what the request payload would be like if I'm trying to call these APIs from an external service like Postman. I wanted something similar this api documentation.
Can anyone help me with this?
Use the Table APIs to do this.
In order to reset a user's password, you basically want to update the user_password field of the user record from sys_user table.
Method: PUT/PATCH
http://<instance>/api/now/table/{tableName}/{sys_id}
here tableName will be sys_user and sys_id will be the sys_id of the user's record in sys_user table.
The body of the API request should be something like this:
{
"user_password": "resetpasswordtext"
}
Bear in mind that this will reset the user's password but the new password will not be "resetpasswordtext". So the user will not be able to login using "resetpasswordtext".
To actually set the password for a user via API, same table API as above can be used. But in order to store the password properly encrypted in the database, below query parameter should be added in the request URL to set the password.
sysparm_input_display_value=true
So the API call will be
Method: PUT/PATCH
http://<instance>/api/now/table/{tableName}/{sys_id}?sysparm_input_display_value=true
BODY: {
"user_password": "newpassword"
}
Now the text "newpassword" can be used by the user to login to the instance.
hope it helps in your use case.
so, my use case did not involve using the Password reset API, but for those of you interested in generating a new password externally, then making an api call to set that as the new password for that user, then here is acode sample that is based on Milind's answer above:
Python3
def change_password_snow(user, pwd, new_pwd, snow_url, sys_id):
# Set the request parameters
url = snow_url + sys_id
# Set proper headers
headers = {"Content-Type":"application/xml","Accept":"application/json"}
# Set query params
params = {"sysparm_input_display_value": "true", "sysparm_fields": "user_password"}
# Do the HTTP request
response = requests.patch(url, auth=(user, pwd), headers=headers, params=params, data=f"<request><entry><user_password>{new_pwd}</user_password></entry></request>")
return response
Setup on ServiceNow
For this to work, the user you are authenticating with in ServiceNow needs to have Admin privileges.
Either that, or modify the sys_user.user_password ACLs to allow non admin users to read and write to that field if they have a role that you select. For my use case, I created a custom role and attached it to that user.
I just finished a starter course in WebAPI.
I went thru token validation.
I want to return a list of items that belong to a user.
The Action Method requires Authorization, but I do not want to use
a session to see the id of the user. However I do not want to pass
the userID as a parameter in the Query from my Angular client.
This would allow another authenticated user to send the ID of a different
user to see their items. I don't want this.
It seems like most WebAPI return results are for common items.
Background...
I'm exploring Parse.com as a back end for an iOS app that also has an html/web browser interface for some users (either via javascript client or asp.net client - to be determined). The web users are 'an audience' for the data/files the app users prepare in the app. They are not the same people.
I need to lock down access to objects in the database (no public access read or write) so I plan to set up an admin user belonging to an administrators role and create an app_users role applying class-level permissions to the various classes accordingly.
Then for my iOS app, using the anonymous users add them to the app_Users role, setting up a default ACL for object level permissions and interact with the data model accordingly.
The app creates PDF files and stores as PFFile objects and I want these to have no public read or write access too. these docs are what will be accessible via the web client.
So...
I don't think i want to use PFUsers for each potential user accessing via a web client -don't want it to over engineered. So I figured send params to Cloud Code (with useMasterKey()) to first return a list of file meta data to present to the user - this works well - I can return the PFFile url or objectId, doc name, file type and size...
The challenge...
Next I'd need to build a Cloud Code function which given objectId or a url will fetch the PDF file and return it in a way my web page can display it to the user.
I've seen a few examples in the Networking section of the docs looks like it might be possible but I can seem to join the dots.
Hope that makes sense - any thoughts?
Edit: Added Code
The code I've been looking at works for text/html - is it possible to response a PDF or binary
Parse.Cloud.httpRequest({
url:'example.com/file.pdf',
 success: function(httpResponse) {
console.log(httpResponse.text);
},
error: function(httpResponse) {
console.error('Request failed: ' + httpResponse.status);
});
I'm new to the whole client-side SPA world. I'm using the above technologies, which seem quite promising. However, one huge snag that I can't get over easily is the lack of built-in security. I had to manually roll out the user authorization, which IMHO should be part of the framework.
Now that I have that sorted, I'm getting major headaches with vertical security: where one user is logged in but can easily access other users' info by changing a few parameters in the browser console. I could pass the userId with every call and then compare it with the one on the server, but I was hoping that there would be an overarching solution that doesn't pollute the breeze data calls with user ids.
For example, let's say there's a call from the data service like this:
function getItems(){
var query = breeze.EntityQuery.from('Items').expand("Person");
return manager.executeQuery(query);
}
this will get all the items, not good. So let's limit by userId:
function getItems(userId){
var query = breeze.EntityQuery.from('Items').where("userId", "==", authentication.userId).expand("Person");
return manager.executeQuery(query);
}
in the second example, we get the userId from the authentication service, which stored the userId when the user was logged in. However, a malicious user can easily go the browser console and change that value.
Of course, I could pass the userId using withParameters(...) and compare it with the current one on the server, but I'd have to do that for every call, which doesn't seem right. Is there a better way to secure calls with the trusted user id?
#Ali - I understand your pain and your concern. You are right to fear any form of so-called security that relies on information passed in the URL. Fortunately there are excellent answers to your concerns and Breeze apps work well with them.
For example, have you studied the ASP.NET Breeze/Knockout Template? It uses Forms Auth for authentication and guards the Web API controller with an [Authorize] attribute. Only logged-in users can access any of the controller methods.
That authentication also sets the IPrincipal which the Web API controller makes available through its User property. You'll see User passed to the constructor of the TodoRepository. In that repository you'll find guard logic to restrict query and saves to just the Todo information belonging to the requesting user.
Look at the network traffic. You won't find any user identifying information in the URL or the request/response bodies. You will see an encrypted authentication cookie in a header.
An obvious flaw in the example is that the client/server traffic takes place in the clear. You must add transport level security (HTTPS) before you go to production. But this is a demo after all.
Why not just do this in the controller?
If the Web Api is secured with [Authorize] then you can get the users ID in the controller and make sure that the data returned is for the currently logged in user.