How can I detect if the user (JID) is already logged in on login when using XMPP? - authentication

In my chat application I want to implement a functionality that whenever a user is already logged in and if he/she wants to login again in some other device using the same username & password, it should revert the user back a message - "You are already logged in somewhere else"
I only know this method to check the logged in status -
connection.isConnected();
But this will not server my purpose.

Alex answer is correct, but let me elaborate it a little bit:
After a successful login your XMPP-IM client will send a presence stanza to the server. The server then replies with the presence stanzas of ever JID in your roster with subscription status 'from' and 'both' (RFC6121 XMPP-IM 4.2.2 and 4.4.2).
Section 4.4.2 also states:
The user's server MUST also send the presence stanza to all of the user's
available resources (including the resource that generated the presence
notification in the first place).
This means that you will get the presence information from every other connected resource of your JID. If you receive here a presence stanza from a different full JID then you used with your current connection you know that a second (or third,...) client is connected with your JID and you display the "You are already logged in somewhere else" message.
Note that this is not really what you want do when using XMPP, as multiple clients simultaneously connected using the same bare JID is a core feature of XMPP-IM.
When using smack, Iterator<Presence> Roster.getPresences(String user) may be used to retrieve the presence information. The call would look something like this getPresences(XMPPConnection.getUser()). (Note that I have not verified if it really works).

after login when you send your initial presence you get the presences of all your other resources (devices). So check all your incoming presences and you will know all your available connections.

Related

Prevent multiple login of same account (Desktop app)

I have a Desktop Application developed with python and pyqt5.
I want to implement a login system for some reasons.
the scenario will be like this (this section is done so far):
Client has created an account on my website and downloaded my desktop application.
They run the application for the first time => A login window displayed asking users to input their data.
The application made a request to URL: http://ip/api/login with a JSON object {username, plaim_pw} (the API developed with Flask).
The API will process that request and check whether that user's data inside that request exist or not and if that PW is correct or not then it will return a response.
If the user successfully logged in then every run time the app will not ask the user again about his/her data, it will be stored somewhere in their machine.
What I want is:
If user ' A' successfully Logged in with account ' X', And at the same time user 'B' trying to log in with the same account that user ' A' is using => Then I want to tell user 'B': "can't log-in at the time because another user using the same account" or something like that. in short description: only one user can use the same account at the same time.
My questions are:
How to accomplish that mechanism? is it good or bad?
I read about JWT, could it be helpful in my case? If so, Then how should I implemented it?
Here is extra information:
I don't have many APIs, I only have a route for "login" nothing more for now, And I want the login system for some reason.
And in the future, I will be using HTTPS instead of HTTP.
Once the user has logged in write this down on the server. Then the subsequent login attempt can check this. When checking consider an expiration timestamp. This can easily solve the first question. Consider looking at topics such as session management: https://en.wikipedia.org/wiki/Session_(computer_science), https://en.wikipedia.org/wiki/Session_ID.
JWT is not necessary for your scenario yet.

detecting link checkers (spam filter) in incoming HTTP requests

We have a site that uses a "one-time" login process for password resets which are not initiated by the user themselves. (for instance, a password reset that is initiated by an admin or another employee) A URL is sent to the user via email which can then be used to reset their password. The URL can only be visited one time. (there's more to this for security-sake but I'll keep it simple) Recently, some users have complained that when they visit the link, it has already expired. The end result is that they can't reset their passwords using this feature. We discovered that the users in question have a spam filter or "link checker" in their environment that they do not have access to. This device visits the one-time link before the user is able to, to make sure its safe.
I'm trying to solve this issue and was wondering if there's a way I can detect these type of devices on the web server when the request is made? When the spam filter visits the link, is there something in the http request that would stand apart from a regular browser? Maybe they all use a specific custom HTTP header? Or maybe there's a regex I could use on the user agent? I haven't been able to catch one of these yet, so I'm not sure what the request looks like coming from a spam filter.
Anyone know of a way to detect spam filters of any vendor by looking at the http requests? I know it's a long shot but maybe they all use a specific header for reasons such as this?
I got approval to modify the design to remove the one-time aspect of the URL. This solves the issue and saves me the headache. Thanks for the suggestion, #PeeHaa

External Login Account vs. Native Login Account

I am brand new to Visual Studio 2012 and MVC 4, and I've been working with the SimpleMembershipProvider via the WebMatrix.WebData library.
I'd like to integrate Facebook as an external login source down the road, but it's not a requirement as of right now. However, to get a decent feel for what it would take, I've been following the tutorial and guide found here - http://www.asp.net/mvc/tutorials/mvc-4/using-oauth-providers-with-mvc.
My question :
If a user has already been created using :
WebSecurity.CreateUserAndAccount(model.Email, model.Password);
WebSecurity.Login(model.Email, model.Password);
Can they be "upgraded" to an oAuthMemebership account in the future, if they choose to use their Facebook credentials instead of the email and password they created when first signing up?
I couldn't find a clear answer to this question in the guide, or elsewhere, so I'm hoping someone can clarify how that process may work.
The SimpleMembership setup allows for a local and multiple OAuth logins all sharing the same UserProfile - so a single user can login with either a local password, or FacebOogLiveWitter.
(I should state, that I'm assuming in this answer that the OAuth provider does not send back a matching piece of information for a local account. If they do then the principles of actually performing the merge are the same, but the complexity and steps are vastly reduced.)
The OAuth registration process will refuse the user if they use an existing user name, rather than try and merge two accounts. Therefore this isn't simple, you'll have to build the functionality yourself. The process is complex as there are many directions the user can approach this from (so you could simplify by only supporting one or two), and you need to enforce security as well in case someone tries to merge into an account they don't own.
I will assume you are comfortable with the link you've posted, and you've followed the Facebook help at (for example) Facebook Login and The Login Flow for Web (without JavaScript SDK) so you have a working test application.
Your general process has to have multiple user journey approaches to make sense to a user:
for a logged in user (with a local account)
let them login to facebook and associate the accounts
let them merge an existing account on your site which uses a facebook login
for a logged-in user (with a facebook account)
let them create a local account
let them merge an existing local account on your site
for a non logged in user who tries to register a local account
let them merge this new account with a facebook login that is already registered, and do that as part of the registration process
for a non logged in user who tries to register (or log in for the first time with) a facebook account
let them link this with an existing local account as part of the registration process
etc.
ASK PERMISSION
(You can skip this if the OAuth provider has sent back a matching identifying piece of information, such as an email address).
You should enforce confirmation security, usually through email confirmation sent to the target account of the merge. Otherwise:
someone can login to your site with facebook for the first time
during that process say they "own" the email address or username of a local account (remember, facebook won't necessarily confirm what their email is for you)
and therefore gain access to the existing local account
So, once the merge "request" is made, you need to ask for permission to proceed from the target account of the merge.
The MVC 4 AccountController
I will use Facebook as our OAuth example. To compare what happens when you register a user on your local authentication framework vs. OAuth:
Local: creates an entry in webpages_Membership and an entry with the same UserId in UserProfile (assuming you are using the default tables for the MVC 4 application template)
OAuth: creates an entry in webpages_OAuthMembership and an entry with the same UserId in UserProfile
Now let's look at what happens when a user signs in using Facebook for the first time:
They click on Login using Facebook (or whatever your button says)
they get taken to facebook to login
they succeed (let's assume that, and ignore the failure case)
they then get sent, invisibly to them, to /Account/ExternalLoginCallback
OAuthWebSecurity.SerializeProviderUserId is called, passing the OAuth details to that Action
They get redirected to /Account/ExternalLoginConfirmation and asked to provide a username for their new presence on your site
If that user name is available then UserProfile and webpages_OAuthMembership entries are created
This process is your chance to "join" the accounts by matching some unique piece of information. As long as you end up with the same UserId in UserProfile, webpages_Membership and webpages_OAuthMembership you should be ok. So we have to intercept the process at the point of /Account/ExternalLoginConfirmation.
If the OAuth provider has sent back a matching identifying piece of information, such as an email address, this becomes simple, test for this in the ExternalLoginConfirmation action, and auto-merge using a similar process to the one outlined below.
However, I think you can't/shouldn't assume that the user uses the same email address for your site and OAuth, (nor should you for many reasons). Also, probably in the T&Cs for something like FacebOogLiveWitter it stops you asking for the email of their account anyway, and if they don't currently they might in future.
So instead, you could link the accounts based on alternatives, like username or email address, or phone number. Either way you are going to need them to input some identifying piece of information that is unique against an account, and will pull back the target account.
Wrapping up
So to put this all together: In the first part of this answer I outlined how you will need to consider multiple user journeys to merge accounts. I will use the example 4.1.
Your process will need to:
(Assumption - when a user first registers with a local account, you ask them for an email address and validate it or assume it is valid)
Let the user login with facebook for the first time
at Account/ExternalLoginConfirmation ask them if they want to
Create a new account with you
Use their facebook login to access an existing account
Assuming the latter, then you log a request in a new table (maybe "MergeAccountRequests") with:
The facebook account UserId
The target merge local account UserId
An authorisation code to use in the email you need to send
(From this point on, if they login without confirming that merge, they will have to get sent to a page to ask them to confirm, rather than create objects in other db tables which you have to worry about later)
You then send an email to the address of the target merge (local) account asking for permission to complete the merge (a standard confirmation email, with a link)
When they click on that link, or enter the code you sent them (you could use SMS as well as email) then you need to merge the two accounts
Choose the "new" and "target accounts (in this case "new" is the facebook account as you don't have data associated with it yet)
Delete the UserProfile of the "new" account
Change the UserId of the "new" account webpages_OAuthMembership table to the same as the "target" account
Log the user out (so there are no complications depending on which account they are currently logged in with)
Display a message to the user telling them the merge is almost complete and that they can now log in with either account to confirm and complete the merge
Rather than send them to a login page, i would give them the login options alongside the confirmation message.

When using OpenDS for SMTP account status notification, how do I include user's name in notification?

We are using OpenDS for SMTP account status notification to notify users when their password is nearing expiration. The SMTP account status notification handler works fine to notify the user and a list of Server admins when the password is soon to expire but we are not able to find a way to have the customer's name in the email.
The notification Handler has no issue pulling the customer's email address and also referencing the password policy to correctly identify the pending password expiriation, so why not also identify the customer by name in the email? All this information is available so how would a variable be set to pull and use this customer information?
The notification handlers are quite powerful but definitely under-documented.
It's possible to identify the user by mail in the email. I've looked at the code of OpenDJ (the actively developed branch of OpenDS, http://opendj.forgerock.org), and you can reference any attribute from the user entry within the template.
More specifically for the mail attribute of the user, you should use this property in the template (templates are under config/message/ directory) :
%%notification-user-attr:mail%%
I haven't tested, but it should work.
I hope this helps.
Ludovic Poitou
PS: I've been told by our technical writer, that all tokens that can be used in the template messages is actually documented as part of OpenDJ administration guide : http://opendj.forgerock.org/doc/admin-guide/index.html#account-status-notification

AppEngine Channel API - Best way to check if a channel is still open (server side)

I have built a social network/dating type application on the AppEngine and am currently in the process of adding a chat built on top of the Channel API. However, the problem that I have is that users may reload or navigate to new pages while the chat is going on (as they can in Facebook). This means that the server doesn't easily know if it should generate a new channel ID token for a given client, or if a given client has already been assigned a channel token.
It would be extremely useful if there were a way to check (server side) if a particular client already has a channel open. For example, if I assign a client "Jack" a channel ID of "Jack-Jan-21-2010", then I would like to be able to check on the server side if there is already a channel open associated with the ID "Jack-Jan-21-2010". This can be (sort of) tracked on the client side by watching for an onerror() and onclose() callback, but I can't see anything server-side that allows me to just check if a channel associated with a given ID is already open.
Does anyone know an intelligent way to check (server side) if a channel has already been opened, while using the AppEngine Channel API?
Part 1: Solving your problem
See Part 2 below if you really need to track client connections, but I'm not sure from your question if what you're asking for will solve your problem.
Let me see if I can echo your problem back: you're writing a chat app, but it's for a site which isn't fully AJAX (in the way that, say, gmail is); the site contains page navigation where you may need to re-set up your channel after the user clicks on a link to another page. When the user navigates, the new page is rendered, and you want to avoid getting a new token at that point; you want to reuse the existing token and channel with the same client-id.
If that's correct, I have two alternate solutions, one easy but with not-great user experience, one trickier but with a much smoother end result.
Preserve the token in a cookie. When you re-render your page, just use the token from the cookie instead of calling channel.create_channel again. When the token expires you'll get an onerror callback just like if the user had stayed on the original page; at this point, call channel.create_channel again. The problem with this is that re-connection can be slow (up to 10 seconds or more in bad cases) because of the nature of Comet connections.
Wrap your entire site that's not chat-related in an iframe. Put your channel creation code and UI in the outer iframe. This way you don't have to re-connect every time the user navigates. This avoids the downtime on navigation. Note that orkut uses this technique, with floating divs, as a small amount of Firebug investigation will reveal.
Part 2: Your feature request
If it turns out I'm misunderstanding and you really do need to track client connections:
There's not a built-in way to check if a client is connected to a channel identified by a client-id now.
However, I am working right now on adding "presence" (in the chat sense) so that your app can register to get a post when a client connects to or disconnects from a channel created with a given client id. You also might be able to "probe" presence, to query whether a given client id is connected or not (still working on the details of this part).
Note that this won't be token-based, but rather client-id based.
I don't have a definite release date for this yet but as I said I'm actively working on it right now.
In the meantime, you could use a heartbeat HTTP request from your client back to your app that says, "hey, I'm still here" every minute or so. You'll need to have some sort of task that runs every, say, 2 minutes and marks any clients that haven't checked in as inactive, and you'll need to store this data someplace.