I have been given a task to sort out a bug in a SilverLight application, however my knowledge of authentication is basic at best so I am quite stuck and looking for help.
The issue is that if a user logs into the application, then opens another browser tab/window and accesses a URL from within the application, this is perfectly acceptable and the system works ok as far as we know. The problem arises when the user logs out of the application from one tab/window and then tries to continue to work on the other tab/window, in which case a variety of errors are thrown depending on what the user does.
We already have a timer in the application to detect connection issues with the database so I thought that checking that the user is authenticated here would be a good start, so I checked for AuthenticationService.User.Identity.IsAuthenticated, but unfortunately that is always true. So I researched and debugged my code and that property is actually set to false once the Logout method has completed, however this doesn't seem to be the case when I debug the application once the user has logged out on the other tab/window.
I have researched on the internet, but all the similar issues I can find are caused by something that isn't relevant, or that I don't understand completely.
The system uses an authentication class which is inherited from FormsAuthentication, but all the Login and Logout functions use the base WCF RIA AuthenticationService service methods.
Could anyone make some suggestions as what could be the issue?
When you log out basically what happens is that the server will destroy your session in the server memory/session state etc. If there is a new request from the same client the server will read the session id cookie and try to match it with one of the existing sessions. If this session will not be found then we will get the exception you are facing.
Having a SilverLight application this is basically a client application which will not send any request to the server until it really requires is ( Service call). I think you should send a log out message to all of your application instances to log out the user also on the client side everywhere else.
Maybe this links will help you
Can silverlight detect or communicate across browser instances?
Writing a javascript file from another javascript
Related
I am creating a .NET class library which will allow local applications to access the accounts of users registered on my website, using an API. I would like the library to handle all authentication of users, so that any app I create an simply call the library, and be returned a token for the API. I'm not sure how to do this authentication.
There are a couple of ways I have considered doing this, however they are not ideal. The first would be to simply create a login form within the library which asks users to enter their login then calls the API. The second method would be to have a webpage where the user logs in and is then given the token which they enter into the app.
The ideal scenario for this situation is that the user does not see their token, and the actual login process is delegated to the website if possible. Both of the above ways lose out on one of those conditions.
The ideal way I would like to do this is inspired from an app I use where if the user is not logged in, they must press a 'Sign In' button, which opens a webpage where they log in. Once they have done so successfully the app automatically detects this and they are signed into the app. The downfall of this solution is that I have no idea how I might do that myself.
Essentially what I'm asking is, is the third solution viable, and how could I do it, or if not are there any better solutions I've overlooked.
FYI the website and API run ASP.NET MVC and WebAPI respectively and the library will use .NET framework.
Edit:
From the comment below it seems likely that you'll want to implement an authentication provider using something like OAuth. The .NET reference libraries can be found here and there's a similar answer already on StackOverflow that may also shed some light.
Welcome to Stack Overflow!
Personally, I would keep the Web API as the authority on authenticating a user and just consume this HTTP endpoint on all platforms (web, desktop, mobile etc) whenever you want to validate a user's credentials.
At a high level the process would be along the lines of:
Have your "clients" (desktop, mobile, web applications) submit HTTP requests to an API route (something like /authenticate) when the user first logs in.
Run your authentication logic
If successful return a token (and cache this this for use in subsequent requests)
Otherwise return a 401 response
Every client will now get a standardised response they can use for determining if they should redirect the user to some protected area, or show them an error message.
This also allows you to design login screens that are native to the platform they're running on (which is a smoother user experience). I wouldn't recommend having a library return a pre-built login page to the user - you'll find that becomes a real pain to maintain!
The third solution you proposed is also a valid way of doing things - but it does have the side effect of redirecting the user's focus away from the application they're using - which you may not want depending on your use case. It's also a bit trickier to implement than just calling the API directly, so unless you have a specific requirement to do it this way I'd not recommend it.
Hopefully this makes some sense. If you are unsure on how to implement cross application authentication then I'd recommend taking a look at some existing answers on Stack Overflow such as:
Basic token checking
OAuth
I am currently working on a project for which there exists both a mobile app and a web site. One task can be performed on either the web site (meant for desktop users) or the app. Right now, the requested functionality for the site is as follows:
If a desktop user visits the web page, continue on that page as usual.
If a mobile user visits the web page, redirect them to the installed mobile app.
I have already implemented logic to tell whether the user is on a desktop or mobile device (most of the time, at least); however, it occurred to me that some users may not have the app installed, or that a desktop device could be incorrectly identified as a mobile device in the future. If a computer that does not have the app installed is redirected, they will encounter some error or an about:blank page. So, my question is, is there any way to tell whether a Response.Redirect to a mobile app will succeed?
So far I have investigated the HttpWebRequest/HttpWebResponse option to try and determine success or failure based on a requested page response prior to the redirect, but this does not seem like a valid option since a URL linked to an app will not provide a valid URI for the HttpWebRequest to test with. Any assistance or advice would be greatly appreciated. Thank you!
For clarification, the redirect looks something like this:
Response.Redirect("opencustomapp://SomePage?Parameter1=bar&Parameter2=foo");
The expected result is not to open a web page, but rather to interact with an app installed on the user's phone which has been mapped to this url.
EDIT: I have accepted the answer that it does not seem possible to do what I was asking for, but in case others have this problem, I wanted to attach some useful links to other questions about how to use a cookie to determine if the app is installed and how to redirect the user to some other place if the cookie is not set. For my own code, I will probably be going with a combination of a user-agent check and the setTimeout() function, as this can be implemented from code-behind using ClientScript.RegisterStartupScript without requiring any changes to the existing app.
No, there is no way to tell at the server if the redirect would succeed. This is because the redirect is sent back to the client from your server and executed at the client. Probably the best thing that you can do is use the mobile app to set a cookie for the website on the device, and then check for that cookie on the server side of the request... if it exists, redirect. Be careful to clear the cookie if they delete the app (if possible, not super familiar with mobile apps), otherwise the redirect would fail.
I'm currently toying around with the Clarity .NET Facebook API but am finding certain situations with authentication to be kind of limiting. I keep going through the tutorials but always end up hitting a brick wall with what I want to do. Perhaps I just cannot do it?
I want to make a Web Service that takes in the require credentials (APIKey, SecretKey, UsersId (or Session Key?) and whatever else I would need), and then do various tasks: Post to users wall, add events etc.
The problem I am having is this: The current documentation, examples and support provide a way to do this within the context of a Web site. Within this context, the required "connect" popup can be initiated and allow the user to authenticate and and connect the application. From that point on the Web can go on with its business to do what it needs to do.
If I close the browser and come back to the page, I have to push the connect button again. Except this time, since I was already logged into facebook, I don't have to go through the whole connection process.
But still ... How do applications like Tweetdeck get around this? They seemingly have you connect once, when you install their application, and you don't have to do it again. I would assume that this same idea would have to applied towards making a web service because: You don't know what context the user is in when making the Web service call. The web service methods being called could be coming from a Windows Form app, or code behind in a workflow.
I would advise you to try Steve's blog and starter kit
you can also find a reference to his post in this so question
Good luck
Edited/Added below
You cannot store the facebook login credentials for users and pass them to FB.
(terms & conditions)
but you can use: offline_access, to access some usage without flagging the user as logged in.
Cool tip from this forum:
Use the following URL with your API Key
http://www.facebook.com/login.php?api_key=YOURAPIKEY&connect_display=popup&v=1.0&next=http://www.facebook.com/connect/login_success.html&cancel_url=http://www.facebook.com/connect/login_failure.html&fbconnect=true&return_session=true&req_perms=offline_access
Register for the Facebook Developer
App on your facebook profile.
Create a new app Web App(By default)
through your "Facebook Developer
App". Change the Application Type to
"Desktop App". Note down the API Key
& Secret Key for you app.
Authorize the app & authenticate the user and
then get the permanent session_key.
Authentication
For a fully logged in session, you are asked to use (again terms and conditions) login.php and you can login via JavaScript
HTH
Ric
So i have a custom CMS running under .Net 3.5 written entirely in c#. The engine is optimized to render for mobile devices, but also server to normal web browsers. It also supports cookieless sessions. Great...
I've chosen not to cache anything (including browser data) in order to control the rendering completely from data. This has been all good until lately.
The engine implements a basic login function that simply logs the user state within a session object.
The behavior is rather strange. User will click through the site no problem. Then login. The login will either go through successfully or just redisplay the login screen, suggesting a cached page being returned or redisplayed... If the login is successful the concurrent page hits will switch arbitrarily between logged in and logged out state... Also suggesting either the session state is not accessible or a cached page being returned.
I have debugged the hell out of the thing.... including using fiddler and the like. When debugging the behavior disappears.
Huh?
One of the sites running on the engine is http://www.wiseguy.mobi (sorry customized for South Africa, so you'll probably not be able to get the password Text Message)!
Ok, so i've been a dumbass...
The issue was related to the fact that my IIS application was running 2 WorkerProcesses. Thus InProc Session state would return different session object states when the user hits either of the worker processes.
This is why the SQL SessionState persistance has resolved it. Either was its set up rather nicely now, and the issues have been resolved...
I have to design a CMS where a set of credentials can only be used once. So if a user has logged in from his computer, no-one can login with his credentials from another location until that user logs out.
Now using the asp.net membership provider out the box, the IsOnline method returns a boolean that reflects the timeout window vs. the last activity date. This is not a viable option for me, because if the user just closes the browser after logging in, IsOnline will still be true. But his session will be destroyed(assuming he's not using Remember Me) so if he tries to log in somewhere else it will say "Sorry you still logged in".
Are there any hard and fast options for doing this..?
I was thinking of forcing the users to be "Remembered" so when he logs in a boolean "IsReallyOnline" will be set to true and vice versa when he logs out.. Although this option has it's limitations, (people turn off cookies, not logging out and closing the browser then sum1 else comes and browser to the site and he's logged in etc....) it seems like the most viable for now?
Any suggestions?
Thanks in advance
You are really asking for something that is outside of the remit of the web. The HTTP protocol is by definition stateless, meaning that at any one time; a server never need know if a client still exists. The newer/older implementations of web server programming languages (e.g. php / asp.net mvc) for the most part shy away from storing any state about connected/active clients.
Some things to ask yourself include:
How long may a user be 'active' on a page without causing a postback? Javascript based pages may allow for a user to interactively be using a page for quite some time before any kind of postback happens.
Will the users be going through a proxy or caching server? Multiple requests from 'different' users may come from the same machine in this case.
Will your application be running on one machine only, or maybe a server farm? You'll need to ensure that load balancing (for example) doesn't punt different users onto different servers allowing multiple logins.
How about a user legitimately using two different browsers on the same machine? Is this to be allowed?
One might suggest your problem here stems from trying to use the wrong technology given your requirements? Maybe writing a client application which uses direct connection to your servers would be more 'secure'? (Yes I understand this is huge hassles but if your one user / one logon requirement is absolute maybe you could explore this avenue?)
Oh alright, a web solution
For a http centric solution you could try a javascript timer making a request to your server every X seconds to indicate that the session is still active. As long as the browser is open and the network connection valid you should be getting these 'pings'. The session is kept open by the cookie passed by the httprequest.
You'll be able to code the 'ping' page to store the user details into either the application object or some membership provider of your choice then interrogate this provider whenever a client attempts to log in.
This will require a relatively short time-out on a session or some other mechanism to ensure that a crashed browser doesn't lock your legitimate user out for too long.
Please note: This will fail horribly if the user doesn't have javascript turned on (Don't assume that they will have!)
Fast Option: Store IsOnline as a session.
Check if session is true, then allow. If not, don't allow.
If user closes browser, he will be logged outas its in a session.