I have an Ionic Angular app which I'm deploying to an Android device. I am using OpenID + KeyCloak for authentication, on the clientside I am taking care of this by using the angular-auth-oidc-client. The configuration I have set up is:
scope: 'openid profile tino_access',
silentRenewUrl: `${window.location.origin}/silent-renew.html`,
responseType: 'code',
postLogoutRedirectUri: window.location.origin,
silentRenew: true,
silentRenewUrl: `${window.location.origin}/silent-renew.html`,
logLevel: LogLevel.Warn,
postLoginRoute: window.location.origin,
useRefreshToken: true
This works perfectly fine when deployed locally or on a custom domain on my server, however when testing on a mobile phone as an app it does not work. I notice that the value of window.location.origin is http://localhost. After successful login, a request is made in the form of ${window.location.origin}/?state='token'&code='token', such that 'token' is the value of the token generated by the OAuth. When this request is made on the mobile device, the request http://localhost/?state=...&code=... is not recognized and the app fails to launch, I only get an error screen that the web page does not exist.
Is there any way to go around this problem?
Thanks
Answer: Since an app's origin is http://localhost, and a local server is not running on the phone, the solution is to change the redirect_url parameter of the auth configuration to the package id of the application. Example: com.package.id://home
This will redirect you back to the app after finishing the authentication in the OAuth page
Related
I am using play-games-plugin-for-unity to authenticate my Unity (Android) game with Google Play Games and pass authentication code to my Python (Flask) server.
While client code works well, I am getting redirect_uri_mismatch error when sending authentication request from my server (which I am running locally).
I have debugged my server code and confirmed that:
I am getting auth code from the client correctly
My redirect_uri is set to postmessage (default value set by oauth2client)
I tried removing "Authorized redirect URIs" (which it created by default when I added linked web app to my game in Google Play Games Console).
Although this seems to be a common problem, I failed to find any examples/references to resolve this while using play-games-plugin-for-unity. As far as I can tell, I does not seem to send any redirect_uris but I can't tell for sure without rebuilding native Android plugin and trying to debug it. I feel like I am missing something simple here.
Here is my server code:
from oauth2client import client
credentials = client.credentials_from_code(LINKED_WEB_APP_CLIENT_ID,
LINKED_WEB_APP_CLIENT_SECRET,
['https://www.googleapis.com/auth/games'],
server_auth_code)
After looking through clientserverskeleton Java example, I found out that passing "" (empty string!!) as redirect_uri works:
from oauth2client import client
credentials = client.credentials_from_code(LINKED_WEB_APP_CLIENT_ID,
LINKED_WEB_APP_CLIENT_SECRET,
['https://www.googleapis.com/auth/games'],
server_auth_code,
redirect_uri="")
After configuring my app on apps.dev.microsoft.com I can login with an administrator account to the mobile application with MSAL. Other users get a 403 -Forbidden when requesting data from Microsoft Graph.
What should be reconfigured for users to grant access?
App Registered Scopes:
User.ReadWrite
User.ReadBasic.All
Calendars.ReadWrite
Contacts.Read
Scope in Android App:
https://graph.microsoft.com/User.ReadWrite
https://graph.microsoft.com/User.ReadBasic.All
https://graph.microsoft.com/Calendars.ReadWrite
https://graph.microsoft.com/Contacts.Read
Requests made by App:
https://graph.microsoft.com/v1.0/users
https://graph.microsoft.com/v1.0/me/events
https://graph.microsoft.com/v1.0/users/{user}/calendarview
https://graph.microsoft.com/v1.0/me/events/{identifier}
I suppose there was an issue with app dev web page or data was not propagated. I removed all delegated permissions from portal and app and with documentation added all permissions for my requests, even if documentation mentioned that I could choose only 1 from it. It worked for first request /users so I did it with another request. After checking that all request works in app I started to removed 'additional' permissions. It ended with only 3 permissions:
"https://graph.microsoft.com/User.ReadWrite",
"https://graph.microsoft.com/User.ReadBasic.All",
"https://graph.microsoft.com/Calendars.Read"
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 am very new to cordova developing. I am trying to develop one login page in android app, i need to access username and password from database for checking credential. Now i am hosting one web service and just pass the user name and password to that service using ajax request and proceed based on value returned from webservice. I dont know is this the correct procedure?. I am sending user name and password through ajax post, i think its insecure.Can you please suggest the best wasy to access database in cordova? I am using visual studio IDE for developing. I used following code to send username and pwd to webservice.
$.ajax({
url: 'localhost\service\Controller',// hostedd in iis
data: JSON.stringify({ username: 'user1', password: 'pwd' }),
sucess: function (data) {
//perform operation for login success
},
error: function () {
}
})
Thanks
Follow these steps:
If you use external urls, then white listen them:
http://cordova.apache.org/docs/en/dev/guide/appdev/whitelist/index.html
Use only https.
Verify the footprint of your cert by using this plugin:
http://plugreg.com/plugin/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin
Don't send the password, send the hash of the password. Use the same algorithm which you use in the backend for creating the hash.
Create a device UUID, save it on the device and send it to the backend and save it the first time, the device called the backend. Use this UUID for logging the device activity.
On every request to the backend, send the device UUID and check it.
Make sure, that you have a way in the backend to stop the activity of a device and user.
In some of my apps, I use the device UUID for individual encryption.
If you want, you can encrypt your whole app by using this plugin:
http://plugreg.com/plugin/EddyVerbruggen/SSLCertificateChecker-PhoneGap-Plugin
In some of my apps (B2B apps), I use an authorization which is working via QR code. In the backend I create some individual «secure Infos» and show them as an QR code. In the app you have a barcodescanner which scans the info , which is then saved on the device. Works great and this is a good way to have individual keys on the devices.
I'm trying to implement one-time code sign in flow in my system.
Application contains of two parts:
1)Android application which requests Google+ for one-time authorization code
2)Rails server that receives one-time code from android application in request header and tries to exchange code for access_token and id_token from Google+
The problem is that everything works well if I get one-time code using JavaScript sign-in button in browser, but doesn't work when one-time code is obtained by Android application and then sent to my server.
I'm getting always
"error" : "redirect_uri_mismatch"
My server settings are following:
{ "web":
{ "client_id": "MY_REGISTERED_WEB_APP_CLIENT_ID",
"client_secret": "MY_CLIENT_SECRET",
"redirect_uris": ["postmessage"],
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token"
}
}
Now, how I'm requesting one-time code from Android app:
I use the same MY_REGISTERED_WEB_APP_CLIENT_ID as on my server for requesting one-time code. I don't know, maybe I have to use on Android another client id, that corresponds to my Android application? But all found documentation and articles are pointing to registered
Web app client_id.
Or maybe my rails server should be configured not for web, but for installed type of registered in Google Console apps?
Now regarding redirect_uris.
I've tried to set several redirect_uris in Google Console:
empty field
http://localhost:5000
https://localhost:5000
http://my.deployment.url/auth2callback
Web origins in Google console are set to
- http://my.deployment.url
- http://localhost:5000
Can't figure out what I'm doing wrong.
Actually I don't understand why I need to set this redirect_uris values, since I don't want to have callbacks from Google, I just want to get access_token and use it for accessing Google+.
This is happening because the redirect_uri your android app is using to create the initial login flow is different from the redirect_uri the server is using when it tries to excange the code for an access_token. The redirect_uri the user returns to and the redirect_uri used in the token exchange must match.
The proper redirect_uri in this case is "urn:ietf:wg:oauth:2.0:oob"