Announcement Announcement Module
Collapse
No announcement yet.
Facebook and Twitter Re-Authentication Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Facebook and Twitter Re-Authentication

    I have a case where I'd like to force the user to re-authenticate with Facebook or Twitter. As I understand it, from https://developers.facebook.com/docs/reauthentication/, I should be able to enable this by adding an auth_type param to the authentication request. As far as I can see it's not possible to add this additional parameter, it seems that scope is the only one which is picked up in ConnectSupport#getOAuth2Parameters

    Code:
    	private OAuth2Parameters getOAuth2Parameters(NativeWebRequest request, MultiValueMap<String, String> additionalParameters) {
    		OAuth2Parameters parameters = new OAuth2Parameters(additionalParameters);
    		parameters.setRedirectUri(callbackUrl(request));
    		String scope = request.getParameter("scope");
    		if (scope != null) {
    			parameters.setScope(scope);
    		}
    		return parameters;
    	}
    Twitter has a force_login paramater which looks to be what I need there. https://dev.twitter.com/docs/api/1/g...h/authenticate

    Perhaps I'm missing something and it's already possible to achieve this, if so please could someone let me know what I need to do.

    Otherwise, is there a recommended way to achieve this? From what I can see I'd have to somehow make changes to how ConnectSupport behaves so that it picks up the auth_type or force_login paramaters but this isn't a Spring Bean so I can't simply extend ConnectSupport and inject my version into ProviderSigninController or ConnectController to make the changes I need.

    Thanks in advance

  • #2
    You're correct in noticing that ConnectSupport is focused on specific parameters and doesn't allow for provider-specific parameters. This is an opportunity for improvement and I've created https://jira.springsource.org/browse/SOCIAL-281 to track this work.

    In the meantime, the only way I can see to do this is to subclass ConnectController and override the connect() method to tweak the URL with new parameters before returning it. (Note that I've not actually tried this...just see that it might work by looking at the code.) I agree that this is a bit hacky, but it's the only way I can see to do it at this point.

    (Note that there may be additional issues fall out of this, such as what happens when Spring Social tries to create a connection that already exists. SOCIAL-281 is focused on the specification of provider-specific parameters, but other issues will be opened as necessary to cover the reauthentication scenario.)
    Last edited by habuma; Dec 20th, 2011, 09:31 AM.

    Comment


    • #3
      Thanks for your quick reply and I look forward to seeing that improvement. As it happens, to fulfil my scenario I haven't needed to subclass ConnectController.

      The (simplified) scenario I have is as follows:
      1. User requests to register with my application via Facebook by Posting to /signin/facebook
      2. ProviderSigninController redirects to Facebook for authentication
      3. ProviderSigninController recognises that the user isn't already registered in my application so redirects to my application's signup controller
      4. My application pre populates the signup form from the UserProfile
      5. User submits the signup form along with an email address
      6. My application sends the user a link to this email address for them to confirm their email address and complete registration
      7. User at some point clicks on this link
      8. My application uses the link to verify the user, including that they haven't past some expiry time
      9. My application programatically posts to /signin/facebook in order to signin the user
      10. At this point I'm able to append the auth_type or force_login params to the url received in the response which my application now redirects to
      11. User is forced to re authenticate with Facebook (or Twitter) as the necessary param has been added
      12. ProviderSigninController handles the signin along with my SimpleSignInAdapter


      I'd be interested to hear whether this is viewed as a good way to go about this. What I want to avoid is a user on a shared computer accidentally registering with someone else's Facebook or Twitter credentials, without making the process too onerous on them.

      It would be great if Spring Social enabled this scenario of confirming registration out of the box. The main reason for it is confirming the user's contact details which we can't be guaranteed to get from the provider.

      Of course, I could have missed something really obvious here and I'm going about things the wrong way

      Thanks

      Comment


      • #4
        FWIW: One way to add additional parameters to the authorization request is to create and register a ConnectInterceptor that forces those parameters in. For example, here's a simple ConnectInterceptor that I wrote to force the auth_type in for Facebook connections:

        Code:
        package org.springframework.social.showcase.config;
        import org.springframework.social.connect.Connection;
        import org.springframework.social.connect.ConnectionFactory;
        import org.springframework.social.connect.web.ConnectInterceptor;
        import org.springframework.social.facebook.api.Facebook;
        import org.springframework.util.MultiValueMap;
        import org.springframework.web.context.request.WebRequest;
        
        public class ExtraParametersConnectInterceptor implements ConnectInterceptor<Facebook> {
        
        	@Override
        	public void preConnect(ConnectionFactory<Facebook> connectionFactory, MultiValueMap<String, String> parameters, WebRequest request) {
        		parameters.set("auth_type", "reauthenticate");
        	}
        
        	@Override
        	public void postConnect(Connection<Facebook> connection, WebRequest request) {		
        		// do nothing
        	}
        
        }
        Then you just add it to the selection of connect interceptors when you declare ConnectController:

        Code:
        @Bean
        public ConnectController connectController() {
        	ConnectController connectController = new ConnectController(connectionFactoryLocator(), connectionRepository());
        	connectController.addInterceptor(new PostToWallAfterConnectInterceptor());
        	connectController.addInterceptor(new TweetAfterConnectInterceptor());
        	connectController.addInterceptor(new ExtraParametersConnectInterceptor());
        	return connectController;
        }
        I'm still thinking over it, but this might be the most effective and elegant way to add parameters to the authorization URL. Let me know what you think.

        Comment


        • #5
          That looks good.

          So does that mean at step 9 in my scenario above, I'd post to connect/providerId instead of signin/providerId as I am now?

          Comment

          Working...
          X