I've implemented the OpenID in our Rails app following the instructions found here. It mostly works, but occasionally I get different responses for identifier_url from Google. This causes a duplicate key error when the SessionsController tries to insert a new record for an existing email address with an "old" identifier_url. I end up having to delete the existing entry, ask the user to re-register.
The identifier_url seems to be a hash, so apparently something in my app has changed, causing Google to generate a new hash. It seems to happen occasionally when I re-deploy my app, perhaps because Capistrano is cleaning up sessions/cookies as part of the deploy process.
What goes into the creation of the identifier_url, and how can I configure OpenID to generate them consistently?
Related
I'm using IdentityServer 4 but I think this question applies to ASP.Net identity in general.
We are considering to adapt an external (WinForms) tool to automatically delete (and later also create and manage) users. This tool has direct access to the IdentityServer database.
Is it as simple as deleting the record in the AspNetUsers table (and any additional records in profile/preferences/settings/roles tables) or is it more involved? Would we have to cycle the IdentityServer application pool as well?
In addition, if the user is logged in and actively busy on the Identity Server website, will the cookies be invalid as soon as the user tries to load a page with the [Authorize] attribute (after the record is deleted)?
We'll also have to notify all sites that make use of the tokens coming from the IdentityServer, but it looks like there is an existing solution for that (Backchannel Logout) which looks quite clumsy at first glance... It looks like a request is sent to the client to clear the cookies... I hope I'm seriously misunderstanding something here...
When store owner installs my app I save access tokens into database for later use. Having access tokens from store is huge security responsibility because anybody with these tokens can modify stores from any domain/address, there is no ip or domain lock.
What method could I use to make this more secure? I was thinking to save tokens offline and then upload it only when needed (in case I need to make some global updates for all stores), then delete it again. In case when merchant access app configuration within admin, I would just save it into session. Is there any better method?
Good question.
I save them in a database as well but I encode them with a separate key from the Shopify App password. That way even if someone have access to the database because of some backdoor entrance he won't be able to use them. That said if someone have access to the code he will be able to figure out how to decrypt it since he will have access to the key.
That said I make sure that each and every request is authenticated before I show any response from the server. Since I'm using NodeJS as the back-end I make sure that there are no global variables that can be accessed or modified from different stores. Everything is neatly scoped in separated functions so that the session is scoped for the current store and no other ones will be able to dirty the other store session.
In addition I make sure that there is a webhook that fires when the client uninstall his app in order to clear my database from any information regrading his store.
I know some people are using sessions for this ( online method ) but they pose other problems that I didn't like so I stuck with a database ( offline ) since that is the quicker way to access the App instead of multiply redirects in order to save the session.
As for proposals I can give you a few tips that I learn on my way while building a few basic Apps. ( I'm not an expert on the subject by any means )
don't rely on any cookies when it comes to sensible information
authenticate every request that comes from the front-end
don't trust the user and validate any input that comes from the front-end
don't over-complicate your setup, while it's good to have high security it's bad if it makes your app slow for the user and you lose customers
look to other ready to use popular solutions that can guide you to the correct path
don't get greedy with the App scopes, only request the scopes that you need for you app
remember to clean up after yourself when it's possible but don't over do it ( too many Apps modify the code of customers and break it only to prevent any way to clean it afterwards ) Example use the ScriptTag API instead of a liquid snippet using the Asset API. If you have to use the Asset API add only the parts that you know that won't break a site. Creating a variable is ok if you are using var if the site supports IE11 creating a variable using const or let is not OK or using vanilla JS is OK but using jQuery without knowing for sure that the site has it installed globally is not OK.
More insights on the matter can be seen here:
https://help.shopify.com/en/api/getting-started/authentication/oauth/api-access-modes
https://community.shopify.com/c/Shopify-APIs-SDKs/Best-way-to-store-shops-that-have-installed-my-app-and-their/m-p/402972
I'm seeing a weird behavior in Alexa developer console whereby a skill with a configured endpoint value:
uses some old cashed value of the endpoint (note the url difference with the above one in configuration: https://87d44b5e.ngrok.io/kai/api/v1/alexa) leading to a SKILL_ENDPOINT_ERROR:
The configured endpoint (https://87d44b5e.ngrok.io/kai/api/v1/alexa) is perfectly accessible outside Alexa.
The endpoint value referred to in the exception stack of the device log is different: https://simeonleyzerzon5.localhost.run/kai/api/v1/alexa. I don't know where it originates, but it's a legacy endpoint that I have been using several days ago. As those values expire several times a day one needs to keep them reconfigured in Alexa dev console. Seems it has been cached by Alexa somewhere internally.
The skill has account linking enabled.
I tried cleaning browser cookies, restarting the browser, running it in incognito mode, re-saving and re-building model in Alexa json editor, re-saving the correct value of the endpoint in there, disabling account linking on the dev console, disabling and re-enabling the skill via https://alexa.amazon.com - nothing seems to help. Same error also persists for me in different browsers.
I shared a skill with a coworker by inviting him via Developer Console's | Setting | User Permissions, and he's able to run the skill without errors and not experiencing that erroneous caching behaviors (his skill uses the newly updated endpoint), whereas for me it continues happening.
It seems that Alexa saves a skill's snapshot at some point per user at which time the endpoint value (perhaps some other values too?) is memorized and then reused, can someone explain when this memorizing is happening and how one can reset that?
Is above a correct assumption and if so, is that memorization done to prevent a risk of concurrency related problems when a skill is distributed to (via linking) and hit by multiple users? Or is it intended for something else?
How does one resolve this erroneous behavior?
What is the relationship between users and skills and why is the state for a skill shared by several users is not in synch? How can I trigger a reset and re-synchronization of the skill's state across all users that consume that skill. What makes it go out of synch?
I have this question in mind and I wanted to get other developer's opinion on this issue.
For creating a user (like in Facebook or creating an account in Gmail), some people suggested to have an public/private (means we don't tell developers how to use it) action in API for it. I, however, think it is a security risk as even if it is not documented, a hacker can simple see the calls and http requests when our front-end app is using that api action to create a new user (using a web debugger like fiddler) and can find the url to that action so simple ! like this POST ~/api/user/create
and then he/she can send thousands of requests to create user, users needs to be verified but still he/she is adding a lot of junk users in our database and puts a lot of pressure on our servers.
So the question is how do we handle this? Allow this only on our website or what?
Thanks
You can use CAPTCHA to verify that's a real user.
Half or more of our users fall within a specific demographic that consists of expats. Quite a few of them are couples that share the same machine but have separate accounts. For the sake of data integrity I want to close an existing session on a machine if another log in is attempted with the second user's account. Anyone know how to do this?
Thanks!
UPDATE: Not quite sure how i could use this info yet. Not sure of the syntax either. What object? Can you access it if you don't know whether it exists?
(Object) resource
Gets the actual resource stored in the instance variable
(Object) signed_in_resource
Returns a signed in resource from session (if one exists)
UPDATE2: Getting closer... i think. Perhaps the session cookie is the key. Wondering how i delete it at the end of a session. If one exists, if i delete it, then that kills the existing session and then the login can then begin the new one. Work on this when i get back from my lunch appt.
The answer was so easy. Deleting the cookie terminates the session.
if cookies[:_Applicationname_session]
cookies.delete(:_Applicationname_session)
end
'Applicationname' is whatever the application name is. It is found, among other places, in your application.rb file. e.g.:
module Applicationname
class Application < Rails::Application
IMPORTANT: Don't forget the underscore that preceeds Applicationname.