Pass anonymous PFUser to Cloud Code in Parse iOS SDK - facebook

I'm trying to secure a Cloud function in my Parse app. This function doesn't create objects or anything. It just calls an external API and returns the result. However, to make it secure I'm trying to create an anonymous user using the iOS SDK like so:
PFUser.enableAutomaticUser()
print(PFUser.currentUser())
which outputs
Optional(<PFUser: 0x7fd3535570c0, objectId: new, localId: (null)> {})
So seems like the user is being created. But when I make a request using the PFCloud object, my parse function in Cloud gets a null user:
PFCloud.callFunctionInBackground("<endpoint>", withParameters:[<params_dict>], block: {(result) -> Void in
print(result)
})
Result on console log says "user":null. Does anyone know what I could be missing? Also, is this the best way to ensure requests are coming from my iOS client only, and not from some other source?
Thanks.

Your anonymous user is null because unless you save that user or an object related to it, it will not exist on the server. From Parse documentation:
Anonymous users can also be automatically created for you without
requiring a network request, so that you can begin working with your
user immediately when your application starts. When you enable
automatic anonymous user creation at application startup, [PFUser
currentUser] will never be nil. The user will automatically be created
in the cloud the first time the user or any object with a relation to
the user is saved. Until that point, the user's object ID will be nil.
Also you cannot simply check if a request is coming from an iOS client. The whole point of a REST system is that server does not keep any state, it just responds to the requests from different sources. The sources have to send in their credentials (usually in a from of a security token which is issued by the server during a login) with every request. Server verifies the token is genuine and has not been tampered with before serving the request. Parse provides you with user authentication which makes it easy for you to verify that a logged in user is requesting something. You can then build extra security measures on top of that to make sure only certain users are allowed to access certain data.

Related

Keycloak 15.0.2 - UserFederation and AccessToken mismatch on first run

As the title says, I'm developing a Custom User Storage Provider (here forth SPI) with Keycloak 15.0.2.
I’m having trouble sorting an issue where the very first access token that is issued, does not match the expected format (is missing some fields) but also seems to be issued for a different user, if I am to judge only based on the sub field of the AccessToken generated.
To ease reproduction of the issue, you can find my repository on Github here with a complete sample FE and BE along with the keycloak configuration. I also included samples of the result tokens, jwt.io links and logs on LOGS.md file on the repo.
I think I understand why this mismatch is happening, though.
Due to the fact that I start with an empty collection of users on keycloak, I need to create the users on their first login. All I have to start with is their email address which is input on the login screen.
With this information, I setup a “temporary” Federated User until I get the user data from the “real” IDP on the isValid method (where the user actually logs-in into the third party IDP) and then get his details, which are then used to fill a more complete FederatedUser profile and store it on the userLocalStorage.
It's basically this logic (it's all also explained in comments in the repo's code):
Create an adapter/model based solely on the email from the login form to be used temporarily.
Proceed with normal operation.
Then on the isValid() method:
login the user through the REST call to the backend and get the JSESSION token
on a separate call, call the Current-User REST endpoint to get user details and map them to a Dto object
create a new adapter, based on the Dto object (which already contains all the user details like name, phoneNumber, etc) and from that, add to storage as a ksession.userLocalStorage().addUser() user and enrich with custom attributes (to later be mapped into the AccessToken)
when (and if) added, clean cache with ksession.userCache().clear()
Proceed with normal operation
However, I think that the ID/model of that first temporary user is the one that is actually being used during the issuance of the first AccessToken that is generated and is being cached somehow on some other class which then generates the AccessToken with missing information/not the correct user model.
When I reload the page (forcing it to go through the login flow again), I then get the correct AccessToken with all the fields I expected the first one to have. I also noticed that the sub of the tokens are different, and this is what leads me to this conclusion.
Does this flow/conclusion seem correct to you?
And more importantly, how can I fix this?
I have no way of getting all the user data at first or a way to import it (ideally, I didn’t even wanted to Federate, just some ReadOnly data would have been enough if I could modify the AbstractUserAdapter attributes).
Can I somehow access the CredentialInput outside the isValid method?
That’s the only way I’d have to grab all the user data since the beginning.
I’d really appreciate any help you could spare. The reproduction code is just a clone/docker up away and will replicate the issue perfectly.
Please help me figure out how to make sure the token get properly set/issued the first time around
Thanks

How to send Session ID parameter out FROM Moodle?

I need to send user-specific values to an external system from Moodle. How can I force Moodle to send the session ID (or user ID, activity ID, etc.) to this third-party system? All of the articles out there seem to be written for calling into Moodle but this is not what I need to do.
Important:
I cannot alter the Moodle installation. The solution must only involve editing content. This means I cannot author a new plugin or alter any of the Moodle source code.
Edit:
I do have direct access to the Moodle database from a separate external API. The goal was to use this connection to validate the incoming parameters. However, I still need to be able to construct a parameterized URL to call out the external app. That app would then be able to validate the supplied values against the database. If the session ID is not available then I would need the values regarding the page, user, module, etc. to be sent via the parameterized URL.
For the session id do you mean the current user session? There is a session key stored in $_SESSION['USER']->sesskey but its not really useful data. It expires when a user logs out.
$_SESSION is server side, so you would need to use PHP code which isn't allowed in content for security reasons.
Have you got access to the database? You could pull user id and activity id from there. Otherwise you will need to use an API or a plugin.
EDIT: There is a URL activity that you could use to send data externally. But that would require the user to click the link.
Data includes user and course ids.
https://docs.moodle.org/311/en/URL_resource_settings
I can't think of any solution to send data externally without writing some PHP code or adding a plugin.
You can add javascript to every page via Site administration > Appearance > Additional HTML but the session variables aren't available without PHP.
https://docs.moodle.org/311/en/Header_and_footer

Ionic 3 native facebook login process

I had just finished the login process in Ionic 3 with the native facebook login plugin. Everything seems to work fine.
I get my facebook data and store them with the storage plugin.
Here starts the weird part for me.
I want the next time the user opens the app to be able to pass the authenticate phase automatically and i am not sure which is the proper solution.
Solution 1
When the user login for the first time a store the data so the next time he opens the app in the app.component.ts i check if the data i stored(ex userId) exists.
storage.get('userID').then((val) => {
this.isLoggedIn = true;
this.setRoot(MainPage);
});
Solution 2
I make use of the getLoginStatus function and if returns response.status === 'connected' i assume that the user was authenticated before and the data i stored exists.
Is one of them consider as a better approach?
Do you use a different solution?
Do i need the access token for some reason in this situation or this is useful for a web app only?
I would say it depends on the security you are looking for, is your app dealing with sensitive informations ?
If no then you can simply store the userId (your solution 1) and you are good.
If you are dealing with sensitive data then you should consider to have a more secure system (as an example you have to consider that the user may loose its phone and so the user may want to cut off the access...)
To secure the process with facebook a possible way to go :
send the access_token you get from facebook authentication to a remote server where you can check it (here a link for more info)
save a token to your sever corresponding to your new user (a json web token for example)
send back this token and save it locally
to every authentication check that the token is still valid server side
I recommend you to read the tutorials written by Josh Morony :
https://www.joshmorony.com/using-json-web-tokens-jwt-for-custom-authentication-in-ionic-2-part-2/
https://www.joshmorony.com/creating-role-based-authentication-with-passport-in-ionic-2-part-2/
https://www.joshmorony.com/basic-security-for-ionic-cordova-applications/

Is it okay to configure Parse User with public "get" class-level permission?

I'm in the process of designing my data model for an iOS application where I'm using Parse for the backend (first time using Parse)
Every user of my application has both private data that should be readable and writable only by the owner of the data and public data which should be readable by everyone.
I'm considering keeping my publicly readable data stored in Parse's built in User object and the private data in another custom object. Is there any downside to this? My app uses Facebook Login exclusively and, thus, when a user is created the authData field is populated with "Facebook: 12345..." Is having this accessible to everyone a security problem?
In this scenario the User object (my public data) would need "Get" not "find" permissions, I just need it to be readable by anyone who knows the objectId. So that rules out anyone just dumping my entire User's table.
I've read through the documentation and the "sensitivity" of each user's authData wasn't clear. I realize that if I were using a traditional username/password scheme it would be a problem, but is it for Facebook login? Any help/tips are appreciated.
EDIT:
I printed an entire user object to the console on a test client (with another, different user logged in) and authData wasn't returned. Am I right to assume that my suggested strategy wouldn't be a problem then? authData appears to be a "special" field that isn't returned if another user fetches it.

Authenticating calls from Phonegap app to REST server

I'm building an app with Phonegap. It simply reads xml feeds to display latest articles uploaded by a school for parents to read.
There will be an option where each user of the app can decide whether they want to receive Push Notifications or not. I have a simple database table where the device's registration i.d. from Google Cloud Console is stored. When the user clicks "yes", the registration i.d. is generated and stored on the server. If they then click "no", it's deleted. I want to secure these call to the server with basic HTTP authentification.
Any documentation I have seen on basic authentification describes the sending of username and passwords. But with my application, there is no username or password as the users do not need to sign up. What do I send to authenticate the client? Would there be a key hard-coded on the client side and sent with each request? Couln't this be easily exposed by unpacking the .apk?
I object to the premise of the question. I actually see this as less a security issue and more a preferences issue. Understanding the distinction makes the development of your feature much easier.
Simply modify your application to allow the user to configure what he or she wants to see in the settings and then store the preferences wherever you want on the client (like local storage). The server can then push as before, but the app should simply refuse to render those pushes that the user doesn't want to see.
If you want to simply disseminate non-sensitive content to the users who want to see it, this is a preferences issue and/or a publish/subscribe issue. But it is not a security issue.
Since you have access to server side, you have the control of the whole process. So, in order to handle that, you may think about something like session cookies that a web server creates in case of normal authentication.
I have done something similar and what I've done is to generate a kind of token server side that is stored in the cookies of the device or the localStorage.
So the process flow should be something like this :
Generate a token and store it on the device (cookies or local storage).
For each request, send this value in a http header
From server side, you may identify the user from that token.
For example : you maintain a table that identifies device/token.
That's it
In addition to what the other answers said you can pass a custom useragent string as part of the requests, and validate it matches what you expect. It's not a sure way to 'secure' requests, but along with a (simple) token system and HTTPS this could be enough for your needs.