Why Salesforce.com logs the user in automatically after his/her session has been invalidated?
When you use OAuth2 in a web browsing context, two things happen: (1) the user has to log in to salesforce.com and receive a "sid" (session ID), then (2) the user has to authorize the app if it is not already authorized. What this means is that the user is logged in twice, once with a session ID, and once with a access token.
As long as any browser process from that browser is active, the "sid" cookie will remain valid, up until the point where the sid expires from a session timeout (specified under security controls, session settings). Presumably, your logout function calls /services/oauth2/revoke, which you presume is logging out of both sessions, but is really only revoking the oauth2 access token.
You can prove this by going to your web browser, and visiting your salesforce instance's /home/home.jsp page after logging in from your app; you'll magically be logged in with no prompt. Conversely, log in to salesforce.com, then call your oauth2 login logic...
Here are a few workarounds. Some are kind of destructive (as in, they'll be logged out of salesforce.com if they're working in a browser window...), but you can try them out:
Call /secur/logout.jsp before presenting the oauth2 dialog. This will log them out of their browser, which may prevent them from automatically logging back in (or, it might just select a different user they're logged in to recently...).
Call the multi-site logout page (the link presented on the OAuth2 grant authorization page that reads "Not you?") before attempting to display the OAuth2 dialog. This will log them out of all instances of salesforce, and is probably not user friendly. I don't have this link handy, but should I find it shortly, I'll update this answer.
Figure out how to invoke Private Browsing on the web browser, or an entirely separate browser process, which should create an isolated cookie context. I did a brief search on Google, but didn't come up with a relevant link for this solution. I presume it is most likely possible, I just don't know how. You could probably load MSHTML.dll into your process space and manipulate it directly as an isolated browser process.
Detect the browser's process and manually delete all salesforce.com cookies, then restore them afterwards (to prevent logging them out of their browser as well). I'm not sure this is easy, or even entirely possible, but you might find something on this path as well.
Posted it on StackExchange and got a great answer that helped solve this: https://stackoverflow.com/questions/21248639/using-net-webbrowser-control-why-salesforce-com-logs-the-user-in-automatically
I ran into a similar issue while building a Sinatra-based (ruby) web app for the Salesforce chatter service. Spent ages trying to get the user logout to actually logout and return to the custom app's login page.
Combining the info from the posts here and in the linked post above, I setup this html button:
<a id="logout" href="" >Logout</a>
and this javascript (with jquery) :
$('#logout').click(function() {
$('#layout-page').append('<iframe style="height:0px;overflow:hidden;" src="https://na15.salesforce.com/secur/logout.jsp?display=touch"/>');
window.location="/unauthenticate"; //expire app token and redirect to index page which will bring up login screen in my app
});
The relevant Sinatra code:
get '/*' do
if (session[:auth_hash] == nil) then
redirect '/authenticate'
#redirect '/test'
else
redirect '/feed'
end
#erb :index, :layout => :layout
end
get '/unauthenticate' do
puts session[:auth_hash]
token = session[:auth_hash].credentials[:token]
session.clear
session[:auth_hash] = nil
curl_cmd = "https://login.salesforce.com/services/oauth2/revoke?token=#{token}"
puts "curl cmd: #{curl_cmd}"
`curl #{curl_cmd}`
redirect '/'
end
This worked well.