I have an android application that uses a symfony based api. I have users that login through the phone, send requests to the server and then logout. The problem is that unless I delete the cookies in the android(which I am storing) the symfony server would not log out the user, despite the fact that the user goes to the logout route.
This is part of my security.yml file (And I have tried a lot of combinations with this file to no avail)
firewalls:
api:
anonymous: ~
provider: users
access_denied_url: /user/accessDenied
pattern: ^/api/user
form_login:
login_path: /api/user/login
success_handler: Authentication_Handler
failure_handler: Failure_Handler
check_path: /api/user/login_check
remember_me: false
logout:
path: /api/user/logoutuser
success_handler: logout_handler
target: /
I have also tried triggering controllers manually that call $this->get('session')->invalidate(); and or that redirect to the logout path(some results around the web suggested that was a good idea, but it did not work) It just seems that, whenever cookies exist, the symfony server just logs the user in, that seems like a security issue to me considering that I am saving the cookies into shared preferences on android. Please help
I believe I have located the problem. On logout the cookie headers are not sent, so the server has no idea whose session to invalidate. Making the android httpclient behave like a full fledged browser can be tricky...
Related
I am developing a native Android app that must interact with a Salesforce org through a SOAP API. Currently, for users of the app to login, they must provide a security token alongside their username and password. This makes the login/signup process uncomfortably long and complicated. As far as I can see, the only solution is to whitelist every IP address in my Salesforce org. I would have thought this is a security issue, so I was wondering if there was a better solution.
As far as I can tell, one solution could be to configure my app to log in through a proxy, and then just whitelist the address of that proxy. It was while researching this that I found this https://serverfault.com/questions/514716/whats-the-minimum-required-squid-config-to-make-a-public-proxy-server that made me think that perhaps there is some other more established way to do this, that I am not aware of.
Basically, my question is, is there any way for an android app running on any phone to make requests to an external API that all appear to come from one IP address (possibly through a proxy server) (without doing anything "dodgy")?
Looks like you're solving wrong problem. Why do you want to bypass SF security features so badly.
Try logging in to SF using REST, not SOAP. The session id you'll receive can be used in any API. So if you log in with OAuth2 you might not need security token. You'd need consumer id and secret (but that's just a pair of values you securely generate in SF, not bound to any particular user. You can even use production's values to login to sandboxes).
There's A LOT of reading if you want to do it right. And some prerequisite step of creating a "Connected App". If possible check if your Android library doesn't have something built-in for OAuth logins (to SF, Gmail, Facebook, LinkedIn, Twitter... you can find OAuth/OpenId in few places)
If you want pure background connection without user realising he's communicating with Salesforce - probably the "Username and password" OAuth flow is best for you. That should be minimal changes in your code compared to SOAP login call. It's weak in a sense you still need to have a password (either user's password or some dedicated integration account) - but there's chance that no security token will be needed. Give it a go (examples below) and check user's login history for errors.
If your users have proper SF accounts then maybe another OAuth flow is better. One that ideally displays them with SF login page they trust and just redirects back to your app when login succeeded. (you probably saw something like this if you recently used SF Data Loader?). That way your app doesn't see the password, just the result. And it'll work even if your client wants to use custom domain, decides to enable Single Sign-On...
Sorry, authentication, authorization are massive topics. But there is a better way so I'd want you to make a conscious decision before you code yourself into a corner... If help materials are too dry / too new & full of keywords then maybe try passing some trailheads:
https://trailhead.salesforce.com/content/learn/modules/identity_basics
https://trailhead.salesforce.com/content/learn/modules/api_basics (read intro and REST API part)
https://trailhead.salesforce.com/en/content/learn/modules/mobile_sdk_introduction/mobilesdk_intro_security
Your SOAP login looks probably like that:
POST
https://test.salesforce.com/services/Soap/c/45.0/
HEADERS
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
PAYLOAD
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com">
<soapenv:Body>
<urn:login>
<urn:username>uptonogood#example.com</urn:username>
<urn:password>Nice_Try!111 + security token</urn:password>
</urn:login>
</soapenv:Body>
</soapenv:Envelope>
Corresponding OAuth login (forced to return XML although mobile app should "like" JSON better so if you want - ditch the Accept header I've added)
POST
https://test.salesforce.com/services/oauth2/token
HEADERS
Content-Type:application/x-www-form-urlencoded
Accept:application/xml
PAYLOAD
grant_type=password&
client_id=3MVG9fTLmJ60pJ5JaGv0NNHD5nh6P...&
client_secret=3437814...&
username=uptonogood#example.com&
password=Nice_Try!111
The proper way to do this would be to have your own backend through which you proxy your requests.
e.g.:
Android app -> Your backend -> Salesforce
The issue I'm facing now is related to poloniex public API. For some reason I get the error on web browser on ask reCAPTCHA option.
[3463] BasicNetwork.performRequest: Unexpected response code 403 for https://poloniex.com/public?command=returnChartData¤cyPair=BTC_XMR&start=1405699200&end=9999999999&period=14400
In theorie, API methods are call from a code ( and not directly as a normal webpage on a web browser.)
When you write code to make api call, generaly (except a specific requirement ) you did not setup the "User-Agent".
In your case the User Agent is added on your web browser side.
So it is possible that Poloniex double check "User-Agent" in order to ban not conventional browser ... probably to avoid DDOS.
Last news has confirmed that some fake poloniex android app was stealing API secret and key, so it is potentialy a security feature setup in response to this treat by Poloniex to avoid definitly that "malware" android app could act on wallet without the user permission.
If it is not relative to anti-ddos process it could be relative to mobile ISP applying filter or doing MIM for security.
I am building an App API in Lumen, and I am a bit confused about how to lock down what/who can make requests to it.
At present I have no way of authenticating requests from the app, so anyone who knows the link could make requests from a browser and potentially cause havok. I know in the .env file there is an appkey variable which is currently empty, and after some research I can't seem to find a clear answer on what it actually does and if I need it.
So basically:
If request comes from my app, proceed.
If it comes from anything else, stop it.
That is what I am looking for.
I am using Ionic $http to make the requests.
Any help would be great
App Key is used for encryption which you can read at https://laravel.com/
use below command to generate key
php artisan key:generate
For more info on lumen auth check below github, Lumen 5.3 token auth
github link for lumen token auth
I am currently working on implementing a mobile app for our site that uses Ruby on Rails and Devise. The idea here is, at first, create a mobile login form that on successful login opens a web frame that is authenticated and allows the normal use of the (mobile optimised) site. Theoretically that should be possible.
I am having trouble with the following issues:
How do you get the pure session key for the user session via a json request? What methods can be used to manually generate it from devise, something that the sign_in(:user, user) method does?
Is it even possible to take that key and put it into the browser cookie the way it normally happens in devise, but on the mobile side?
I know that this is not the standard method of making mobile applications for the site, but I believe it should be possible.
You might want to consider using Devise Token Auth and treating your mobile application like just another webapp that requests permission from your main site. DTA is particularly nice since it takes care of managing the session tokens (renewing/expiring) and passing them onto the app requiring access. The issue is overriding your session controllers so that it automatically logs in after you already log in on the mobile app (or just rewriting your log in so it occurs in conjunction with the Rails site, rather than before). Considering you're already using Devise, this may also be more refactoring than you'd like.
If you want to put your authentication form on the mobile UI and pass the credentials over to the web frame, you need a way to pass data from the mobile app to the web frame.
How you accomplish this depends on what platform you're building on. I'm not really a mobile developer so I don't know for certain how difficult / easy these options are:
When opening the web frame, instantiate it with session data
Find a way to call methods on the client from the web frame. Something like getSessionData.
You could generate a fingerprint for the web frame, have the mobile UI send this data to the server, and then have the web frame authenticate with the server by sending the fingerprint.
Again, I'm not entirely sure how possible all these options are.
You should use token authorization and Android deep linking. It will allow you to login in the web browser and send a token to your app via deep linking.
OK, so I decided to make a webframe solution as follows, basically you post the login and password to a certain sign_in method specially designed to generate one-time sign in tokens for the application. You need two methods in the system to do that:
routes.rb
devise_scope :user do
get "sign_in_with_token/:token" => "sessions#sign_in_with_token"
post "get_login_token" => "sessions#get_login_token"
end
sessions_controller.rb (don't forget to add the method that increases the failed_sign_in_count on wrong password, otherwise that can allow brute force attacks)
def get_login_token
user = User.find_by_email(sign_in_params["login"])
password = sign_in_params["password"]
if user and user.valid_password?(password)
token = SecureRandom.hex(16)
user.update_attribute(:authentication_token, token)
render json: {token: token}, status: 200
else
render json: {error: "error"}, status: 403
end
end
and the method to sign in with that token
def sign_in_with_token
#user = User.where(authentication_token: params[:token], email: Base64.decode64(params[:email])).first
if #user
#user.update_attribute(:authentication_token, nil)
sign_in(#user, bypass: true)
end
redirect_to '/' # or user_root_url
end
That way the mobile app will work like this:
use the generic web frame to send ajax requests to the server and get that token for the user email if password is correct.
make a /sign_in_with_token/#{token from ajax}?email=#{base46 encoded email} link inside the app.
open that link inside the web frame and use the app as though you were logged in normally. Now the app can save email and password locally and use that logic to get the token again for another session. Later logging in will also be able to set the app id so that push notifications can be sent.
Appreciate any feedback or criticism on this solution.
I have created an android app that is using a custom-rolled authentication method by calling a web service (webapi on .net mvc 4) with HttpClient. When the user is authenticated, the action method on the server is setting the forms authentication cookie and then returns a user model back to the android client. That user model contains the internal user id and a few other properties.
After the user is authenticated, I'm opening up a WebView on android to serve up a viewport for some simple navigation elements. That WebView needs to be handed the authentication cookie from the webapi call in the previous step. I assume that the forms authentication cookie is being held in the HttpClient (though I can't confirm this) and if so, is there a way to pass that cookie over to the WebView so the web page that is served up in the WebView knows who the user is based on the first step?
If this isn't possible, can someone guide me with some steps to make this work.
TIA
This looks like a very similar problem. Set a cookie to a webView in Android.
Hopefully this can assist you.