Announcement Announcement Module
Collapse
No announcement yet.
SocialAuthenticationFilter sample forthcoming Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • SocialAuthenticationFilter sample forthcoming

    There has been a great deal of interest in the new SocialAuthenticationFilter (SAF) work that was started by Yuan Ji and that I'm now polishing and preparing for a milestone release (hopefully this week). I've received many questions about it, including several via private email.

    Understandably, this is a popular bit of work. SAF will solve the same problem as ProviderSignInController (PSIC)--that is, offering sign-in-with-provider functionality. It will do this with tighter integration to Spring Security, as part of Spring Security's filter chain. ProviderSignInController, on the other hand, will work with Spring Security (as it always has), but will be flexible enough to work with security mechanisms other than Spring Security.

    Be aware that I have a modified Spring Social Showcase sample that uses SAF instead of ProviderSignInController in a local branch. I'm planning to share that on GitHub soon and hopefully that will clear things up. Since this is still a work in progress, I'm hesitant to push it yet, for fear that it may create more questions than it answers. But know that it should be there sometime soon. I'll follow up on this thread when it's available.

  • #2
    Originally posted by habuma View Post
    Be aware that I have a modified Spring Social Showcase sample that uses SAF instead of ProviderSignInController in a local branch.
    Will examples include 'FB canvas app' (spring-social-canvas) using SAF?

    Comment


    • #3
      No, the example will not including doing FB canvas app with SAF. That's because neither SAF nor PSIC are really suitable for FB canvas apps. (Yes, I know that the Spring Social Samples canvas example uses PSIC, but I intend to correct that. See https://jira.springsource.org/browse/SOCIALFB-65.)

      Both SAF and PSIC go through the typical OAuth 2 flow to obtain an access token. But FB canvas apps don't need to do that. Instead, Facebook will POST to the canvas URL of your application with a signed_request parameter. Encoded in that parameter is the access token. No OAuth 2 authorization flow is required.

      What is needed is a simple Spring MVC controller that handles that POST request and uses SignedRequestDecoder to extract the access token. After that it would do pretty much the same as what ProviderSignInController does in its oauth2Callback() method, except that instead of using ConnectSupport to complete the connection by exchanging the code for an access token, it just uses the access token that it was given via the signed_request parameter.

      It bears repeating: FB canvas apps use signed_request to give the access token to the app. That is a very different process than what either PSIC or SAF currently support.

      I suppose that it's possible to adapt/extend ProviderSignInController (and possibly SocialAuthenticationFilter) to handle the signed_request, but I'm not likely to do that. The signed_request is a FB-only feature for canvas apps, while PSIC and SAF are generic to all providers.

      At the moment, however, I'm focusing on the common use case for SAF and not considering how it might play into a FB canvas app.

      Comment


      • #4
        Thank you for explanation, the difference it is getting more clear.

        I also would like to ask your opinion, how do you think about solution for two cases....

        Say, I want web-app to be a 'canvas app' with FB integration using offered approach with SignedRequestDecoder.
        At the same time app exists as stand alone app and we want users to register/login via FB (or something else) using SAF or PSIC approach.

        How do you think, is that possible inside one app ? Of course, it's 'open question' and it 'depends on...'. How do you think if there difficulties are possible integrating two cases in one app?

        Comment


        • #5
          I foresee no difficulties using the standard canvas app approach alongside SAF or PSIC. In fact, you can use SAF and PSIC together (I have been doing that to some degree in my testing), although it doesn't make much sense in practice to use them together. So long as they don't get in each other's way (e.g., listening on the same endpoint URL), it should be fine.

          Comment


          • #6
            I wanted to remind you, SignedRequestDecoder has package level visibility only. Hope you'll pull it up for outside package usage.
            The same about class SignedRequestException
            Last edited by blandger; Jan 22nd, 2013, 04:27 PM. Reason: exception is added

            Comment


            • #7
              Craig, could you please post info about configuration parameters from social canvas sample? I mean Facebook config params as canvas url, web site url in FB account.

              Comment


              • #8
                Yes, I will do that. In fact, I spent some time last night converting the canvas sample to do things the proper way. It's not quite finished, but I'll try to get it out there soon. When I do, I'll also document (somehow...probably with a blog entry) how to configure the app in FB as well as what beans are required in Spring to work with FB canvas.

                Be aware, however, that my priority at the moment is to complete the SocialAuthenticationFilter. This significant work needs to be released in a milestone release. I am hoping to finish it up this week, although I have had some distractions that are making that less likely.

                Regarding the package scoping of the classes you mentioned, that's largely because (and I had forgotten about this) the @SignedRequest annotation is what you should use to have the access token injected into your controller method. I suppose that there's no reason for those to remain package-scoped, though. The ideal approach is to use @SignedRequest, but there's no reason to keep SignedRequestDecoder private. I'll look into exposing that, too.

                Comment


                • #9
                  Craig, I'm trying to create controller for 'canvas app' but I'm stopped on error:
                  Ambiguous mapping found.....
                  See post here:
                  http://forum.springsource.org/showth...ST-mapping-why

                  Is there chance I'm getting that errir because spring-social/security + spring-social-facebook were compiled with 3.2.0 instead of 3.1.3 ?
                  How do you think, will it work if I recompile them back to 3.1.3 and exclude 3.1.3 dependencies on build with 3.2.0 ??

                  In fact, I spent some time last night converting the canvas sample to do things the proper way. It's not quite finished, but I'll try to get it out there soon. When I do, I'll also document (somehow...probably with a blog entry) how to configure the app in FB as well as what beans are required in Spring to work with FB canvas.
                  ......I am hoping to finish it up this week, although I have had some distractions that are making that less likely.
                  Sounds good, although I need my code working 'yesterday' (last week actually). !#@!#$%$%&$^*&((%&*&%$^#@$%@%

                  Comment


                  • #10
                    Craig, could please give an advice with 'canvas' app implementation?

                    The question what is the best approach to update 'Connection' record using data from 'signed_request' parameter?

                    Say I can get 'access_token' from 'signed_request' by controller code, but I can't directly update 'oauth_token' + 'expires'
                    Code:
                        @RequestMapping(value = "/canvas", method = RequestMethod.POST)
                                NativeWebRequest request,
                                Model model) {
                    ......
                                  Map<String, ?> decoded = decoder.decodeSignedRequest(signedRequest);
                    
                                  String providerUserId = (String)decoded.get("user_id");
                                  String oauthTokenValue = (String)decoded.get("oauth_token");
                                  Integer expiresTimeValue = (Integer)decoded.get("expires");
                    
                           // check is it first access attempt or rather consequent access ?
                                  if (providerUserId == null &&
                                            oauthTokenValue == null
                                            && expiresTimeValue == null) {
                                       // OAuth dance flow......
                    
                                       /// Connection<?> connection WILL BE STORED HERE AT FIRST TIME 
                    
                                    } else {
                    
                                    /// Good, that is second access, let's create Internal User...
                                        ConnectionKey key =  new ConnectionKey("facebook", providerUserId);
                    
                                        org.springframework.social.connect.ConnectionRepository connectionRepository =
                                                usersConnectionRepository.createConnectionRepository(providerUserId);
                    
                                        Connection<?> connection = connectionRepository.getConnection(key);
                    
                                // it would be good to update connection :
                                connectionRepository.updateConnection(connection);
                    
                                // but there is no setter on Connection<?> connection !!! OPS.....
                               connection.setOauthToken(oauthTokenValue);
                               connection.setExpiresTime(expiresTimeValue);
                    
                             // That's good I can call to FB API !!!
                               facebook = facebookServiceProvider.getApi(oauthTokenValue);
                    .........
                    Should I'd better use custom 'work around' code ?

                    Comment


                    • #11
                      You don't update the existing connection. If the token is new, you remove the old connection and create a new one. I know that to work, because I've got some experimental code to do just that (experimental code that I need to dust off and make non-experimental soon...but that's a problem for another day).

                      In short, at the moment, there is no *direct* support in Spring Social for working with canvas apps. But that doesn't mean it can't be done.

                      With regard to the question of how it can be done, I'm working on an example to show how to do that. But I have other items already in progress that take a higher priority (and are being asked for with just as much urgency as your request), so I must ask for your patience in this matter. I promise that I will try to squeeze in the updates to the canvas sample as soon as I possibly can. Believe me when I say that *I* really want to complete that sample, as the obsessive/compulsive side of me can't stand that there's a wrong canvas sample and a gap in coverage there. :-)

                      In the meantime, if you happen to dig around discover an approach that works for you, I encourage you to post your findings here or to blog about it so that the community can learn from it.

                      With regard to building against 3.2.0 vs. 3.1.3, Spring Social (as I'm building it) is compiled against Spring 3.1.3. I can't speak for Spring Security or for your own project. But from what I see in the other thread, it looks like you had two of the same controller in play (one from a @Bean declaration and one from component-scanning). That would explain your ambiguous mapping problem.

                      Comment


                      • #12
                        Originally posted by habuma View Post
                        You don't update the existing connection. If the token is new, you remove the old connection and create a new one. I know that to work,..
                        Thank you, I'll try to go that way.

                        In short, at the moment, there is no *direct* support in Spring Social for working with canvas apps. But that doesn't mean it can't be done.
                        Sure, I'm in that game now.

                        With regard to the question of how it can be done, I'm working on an example to show how to do that.
                        I just trying to ask your advice in order to fix my code with less efforts later when you release new version.

                        But I have other items already in progress that take a higher priority (and are being asked for with just as much urgency as your request), so I must ask for your patience in this matter......
                        I see, take your time.

                        In the meantime, if you happen to dig around discover an approach that works for you,.......
                        I have to do that, no much choices for now.

                        I encourage you to post your findings here or to blog about it so that the community can learn from it.
                        I'll try.

                        With regard to building against 3.2.0 vs. 3.1.3, Spring Social (as I'm building it) is compiled against Spring 3.1.3. I can't speak for Spring Security or for your own project. But from what I see in the other thread, it looks like you had two of the same controller in play (one from a @Bean declaration and one from component-scanning). That would explain your ambiguous mapping problem.
                        Yes, that was simple and stupid error, but nobody could give good advice.
                        I'm using Spring Social + Social Security + Social FB compiled against 3.2.0 and don't see something strange at that time.

                        Comment


                        • #13
                          Originally posted by habuma View Post
                          You don't update the existing connection. If the token is new, you remove the old connection and create a new one. I know that to work, because I've got some experimental code to do just that (experimental code that I need to dust off and make non-experimental soon...but that's a problem for another day)........
                          I don't see it's a good idea.
                          If I remove Connection from DB the only way to recreate it make almost 'full OAuth dance' flow.
                          Code:
                          org.springframework.social.connect.web
                          public class ConnectSupport {
                          ......
                          	public Connection<?> completeConnection(OAuth2ConnectionFactory<?> connectionFactory, NativeWebRequest request) {
                          		String code = request.getParameter("code");
                          		try {
                          			AccessGrant accessGrant = connectionFactory.getOAuthOperations().exchangeForAccess(code, callbackUrl(request), null);
                          			return connectionFactory.createConnection(accessGrant);
                          ..........
                          I hardly think it's a good idea to send FB user with 'confirmed FB app' permissions and already installed FB app.
                          Having only limited info from 'signed_request', I would like update existing record for FB user with new 'auth_token', 'expired_time' values and go. I have not much experience with that stuff. That my thoughts from code and my efforts.
                          Dig that stuff farther...

                          Comment


                          • #14
                            As promised, some new sample code demonstrating the use of SocialAuthenticationFilter is now available. Specifically, you'll want to have a look at the following four examples:

                            - https://github.com/SpringSource/spri...ocial-showcase
                            - https://github.com/SpringSource/spri...l-showcase-xml
                            - https://github.com/SpringSource/spri...l-showcase-sec
                            - https://github.com/SpringSource/spri...owcase-sec-xml

                            The first two examples listed here actually have nothing to do with SocialAuthenticationFilter, but do show an equivalent configuration that uses ProviderSignInController for provider signin instead of SocialAuthenticationFilter.

                            The second two examples use SocialAuthenticationFilter instead of ProviderSignInController. One uses Java-based configuration and the other uses XML-based configuration. (Note that I've also updated both XML-based apps to be completely XML-configured; previously it was only the Spring Social bits that were XML-configured.)

                            All of these examples build against the latest snapshot builds of Spring Social. As this is working against snapshot code, consider it a work-in-progress and subject to change as I continue to polish the code. Now that this is complete, I hope to push a new milestone build later this week.

                            Comment

                            Working...
                            X