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.
Related
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 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...
I have a WebView embedded in my application. I am trying to view a webpage that uses NTLM authentication. How can I perform the NTLM authentication using the WebView and view this page?
I was successfully able to authenticate to this page using DefaultHttpClient and the JCIFS Library. But how can I do it for the WebView?
It has been two years since I asked this question. In the meantime, I figured out the answer to this question -
WebView supports NTLM authentication out-of-the-box. The onReceivedHttpAuthRequest callback in WebViewClient has a method parameter a method parameter named handler. This is of the type HttpAuthHandler. handler.proceed(username, password) will automatically authenticate to the web server using NTLM protocol. This handler abstracts the authentication protocol used. Both Basic and NTLM authentication work using the same line of code.
I'm having the same problem! There is another indirect way. You get the HttpResponse and then save the html file to the internal storage and then load the file into the WebView. I never tried this before, though.
I have 3 entities:
1.Android Phone
2.Local Server
3.Fb Server
I want user to login from his phone on to FB , but once authenticated , I want to be able to pull data into local server from FB(no data on to phone).
What is the best way to do this ?.
Is there a way to do this using oAuth ?
This is certainly no problem. Just implement the server-side authentication flow on your web server. Instead of placing a login button on a website where you redirect the user to the Facebook dialog, you open the browser on the smartphone (or embedd a Webview) with that URI. The redirect_uri then points to your web server callback, where you receive the authorization code. Then you exchange that code for an access token by calling Facebook from your server and you're done.
On the phone, point the browser to:
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID
&redirect_uri=https://YOUR_SERVER/YOUR_CALLBACK
&scope=COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES
&state=SOME_ARBITRARY_BUT_UNIQUE_STRING
After handling the callback, issue a request from your server to:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&redirect_uri=https://YOUR_SERVER/YOUR_CALLBACK
&client_secret=YOUR_APP_SECRET
&code=AUTHORIZATION_CODE_YOU_RECEIVED
Basically I would like to connect to the WCF windows service from android with authentication. I am an android developer. I have tinkered with the WCF Rest service from this article and also configured the https.
Now I need to think about the authentication process (to the username and password in the database) to the WCF service from android. Should I encode username and password in the url and do http post, while returning a token for authorization, for login process and use the token and username for subsequent operation(and also save encrypted username and token in a pref file to avoid logging in next time, thus avoiding password)? Any advice and pointer to any project and document is welcomed.
There is a similar question at the programmers https://softwareengineering.stackexchange.com/questions/93005/designing-authentication-for-rest-api but I want to keep this question open since I would like to add useful code and links here.
Instead of encoding the username and password in url, they should be in the request body. The reason is that even though https encrypt the url, it is not a good practice because if the url is called from browser, the browser will remember it and username/password will be visible there in the browser history. Thus, here is an article to handle http Post http://www.codeproject.com/Tips/150313/Simple-WCF-web-service-to-receive-parameter-from-H
If https is achieved with self-signed certificate, you will need do some extra works
http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/
More article on WCF rest and android http://fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx
Creating a custom token in C#
http://msdn.microsoft.com/en-us/library/ms731872.aspx