Page 2 of 2 FirstFirst 12
Results 11 to 17 of 17

Thread: Possible problem with Internet Explorer

  1. #11
    Join Date
    Jan 2013
    Posts
    7

    Default

    Quote Originally Posted by blandger View Post
    2.
    Main processing flow goes in controller with some code parts borrowed from showcase example's 'ProviderSignInController':
    Code:
    @Controller
    @RequestMapping("/canvas")
    public class CanvasProviderSignInController {
    
        private SignedRequestDecoder decoder;
        @Autowired
        private final SocialAuthenticationServiceLocator socialAuthenticationServiceLocator;
    
         private final UsersConnectionRepository usersConnectionRepository; // mongodb repository class
         private final ConnectSupport webSupport = new ConnectSupport();
    
        @Autowired
        private FacebookServiceProvider facebookServiceProvider;
    
        private Facebook facebook;
        private AccountService accountService; // custom helper mongodb service class
    
    ........... // other stuff
    
        @Inject
       	public CanvasProviderSignInController(
                SocialAuthenticationServiceLocator connectionFactoryLocator,
                FacebookServiceProvider facebookServiceProvider,
                UsersConnectionRepository usersConnectionRepository,
                SignInAdapter signInAdapter,
                SignedRequestDecoder decoder,
                Facebook facebook,
                AccountService accountService
                ) {
    ........... //constructor called from custom 'SocialAndSecurityConfig' configuration component class
    ......
    
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String processAccessToCanvas(NativeWebRequest request, Model model) {
            log.error("Error accessing canvas FB app. 'signed_request' can't be found in GET access. Redirecting to " + baseErrorPage);
         ........ // USER CAN'T use app by GET url
       }
    
        @RequestMapping(value="/", method=RequestMethod.GET, params={"install"})
        public String installApplication(
                @RequestParam String install, Model model, NativeWebRequest request) {
          .......... // I have my own 'canvas app install link' and I show it on 'error' page
            OAuth2ConnectionFactory<?> connectionFactory = (OAuth2ConnectionFactory<?>)
                    socialAuthenticationServiceLocator.getConnectionFactory("facebook");
            String authorizationUrl = buildFacebookRequestUrl(request, connectionFactory);
            model.addAttribute("authorizationUrl", authorizationUrl);
            return "/facebook/signin"; // page with inlined JS script to go to 'install FB app' page
    
       }
       	@RequestMapping(value="/", method=RequestMethod.GET, params={"error_reason"})
       	public String canceledAuthorization(
                   @RequestParam String error_reason, Model model, NativeWebRequest request) {
               log.error("Cancelled installing canvas FB app. 'signed_request' value is not found in GET access. Redirecting to " +         baseErrorPage);
           //  user cancelled usign fb app, offer him to install app again by providing link on page
               ..........
                // url for installing FB canvas app by inline JS code on target HTML page
               model.addAttribute("facebookInstallAppUrl", canvasAppInstallUrl);
       		return baseErrorPage;
            }
    
        private String buildFacebookRequestUrl(NativeWebRequest request, OAuth2ConnectionFactory<?> connectionFactory) {
            String authorizationUrl = webSupport.buildOAuthUrl(connectionFactory, request);
            String sessionId = request.getSessionId();
            if (sessionId != null && !sessionId.isEmpty()) {
                authorizationUrl += "&state=" + sessionId;
            }
            authorizationUrl += "&scope=email"; // all necessary FB app permissions go here
            return authorizationUrl;
        }
    
    /// The main working method goes here:
    
    @RequestMapping(value = "/", method = RequestMethod.POST)
        public String processFaceBookCanvasRequest(
                NativeWebRequest request,
                Model model) {
            // get 'signed_request' parameters POST-ed by FB
            String signedRequest = request.getParameter("signed_request");
            // create Spring Social connection factory for later use
            OAuth2ConnectionFactory<?> connectionFactory = (OAuth2ConnectionFactory<?>)
                    socialAuthenticationServiceLocator.getConnectionFactory("facebook");
    
            if (signedRequest != null && !signedRequest.isEmpty()) {
                Map<String, ?> decoded = null;
                try {
                    // try to decode 'signed_request'
                    decoded = decoder.decodeSignedRequest(signedRequest);
                } catch (SignedRequestException e) {
             ..............
    
                try {
                    // facebook returns 'basic' data first access time
                    Map<String, String> userMap = (Map<String, String>)decoded.get("user"); // that data is known every time
    
                    // that fb data exists ONLY when user installed fb canvas app in his FB profile
                    String providerUserId = (String)decoded.get("user_id");
                    String oauthTokenValue = (String)decoded.get("oauth_token");
                    Integer expiresTimeValue = (Integer)decoded.get("expires");
    
                    // If user has canvas app installed in his FB profile ?
                    if (providerUserId == null &&
                            oauthTokenValue == null
                            && expiresTimeValue == null) {
                        // user DON'T HAVE canvas app installed in his FB profile
                        // new user, redirect to 'install FB app' page
                        String authorizationUrl = buildFacebookRequestUrl(request, connectionFactory);
                        model.addAttribute("authorizationUrl", authorizationUrl);
                        return "/facebook/signin"; // page with inlined JS script to go to 'install FB app' page
    
    
                    } else {
    
                        // user DO HAVE canvas app installed in his FB profile
                        // that should be registered user
                        // user can be 'temporary' which is created by Spring Social in UserConnection table (not fully registered)
                        // user can be 'fully registered' by our app and has 'completed User/Profile' stuff with UserConnection record related to him
    
                        ConnectionKey key =  new ConnectionKey("facebook", providerUserId);
                        ConnectionRepository connectionRepository =
                                usersConnectionRepository.createConnectionRepository(providerUserId);
                        Connection<?> connection = null;
                        try {
                            connection = connectionRepository.getConnection(key);
                        } catch (NoSuchConnectionException e) {
                            // something is wrong, userConnection is not found - go to install FB app again
                            String authorizationUrl = buildFacebookRequestUrl(request, connectionFactory);
                            model.addAttribute("authorizationUrl", authorizationUrl);
                            return "/facebook/signin"; // page with inlined JS script to go to 'install FB app' page
                        }
    
                        // find 'temporary' user created by 'Spring Social' code internally (custom code)
                        User notExistedUser = accountService.findOneByProviderUserId(providerUserId, providerUserId);
    
                        if (notExistedUser != null) {
                            // this is really 'new' user, but he should finish registration first
                            facebook = facebookServiceProvider.getApi(oauthTokenValue);
                            FacebookProfile userProfile = facebook.userOperations().getUserProfile();
                            model.addAttribute("profile", userProfile);
    
                            handleSignIn(connection, request, model);
                            // redirect user to page for finishing registration
                            String resultView = "redirect:/facebook/finishRegistration";
                            return  resultView + "?providerUserId=" + providerUserId........ // pass other params from FB profile
    
                        } else {
    
                            // let's find 'internal User' who has finished registration previously  (custom code)
                            notExistedUser = accountService.findOneByUserConnectionValuesInSocialSet(
                                    providerUserId, "facebook", providerUserId);
    
                            if (notExistedUser != null) {
                                // we have completely registred User
                                HttpServletRequest httpRequest =
                                                (HttpServletRequest) request.getNativeRequest();
                                // make automatic login into system via Spring Security
                                AccountUtils.setLoginUserAccount(notExistedUser, httpRequest);
                                return "profile/profile"; // show his profile
    
                            } else {
    
                                // it's should not happen, but let's have error processing
                                model.addAttribute("error", "Canvas Facebook App user not found error");
                                return baseErrorPage;
    
                            }
    
                } catch (Exception e) {
                    log.error("Exception while handling 'signed_request'/'authToken' value (" + e + "). Redirecting to " + baseErrorPage);
                ..................
            }
            log.error("'signed_request' value is not found (" + signedRequest + "). Redirecting to " + baseErrorPage);
            model.addAttribute("error", "'signed_request' value POST-ed by Facebook is not found");
            model.addAttribute("error_description", "Looks like you are trying to install Facebook App outside of Facebook site ?");
            return baseErrorPage;
        }

    Hi blandger,
    could you please create a complete sample for this solution. I would be really grateful and I believe many others will be too.

  2. #12

    Default

    Quote Originally Posted by tirbison View Post
    Hi blandger,
    could you please create a complete sample for this solution. I would be really grateful and I believe many others will be too.
    I can't promise to do that, I can try to create another example on weekends (or later) but not earlier...
    There are many reasons... This is my work project, it has rebuilt social libs, the mongodb is used as back-end, thymeleaf library is used as view layer. So I would be not very easy to adapt project main parts for such example.

    The more then week ago when I just started that journey, I would be really grateful for the same example to everyone who could help. There are only two people who could give good advises and allow borrow they code: Craig and Yuan Ji ( www.jiwhiz.com )

    Thank you guys.
    Best regards.

  3. #13
    Join Date
    Aug 2004
    Posts
    1,072

    Default

    Trust me when I say that I'd love nothing more than to set aside what I'm working and cook up that example. Not that what I'm working on isn't cool stuff, but the canvas sample sounds like a nice fun diversion. And I suspect that the effort will flesh out some improvements needed for Spring Social to make the canvas experience even better.

    But, I'm too close to finishing up the work that's currently on my plate, so I really should put a bow on it and then turn my attention to the canvas sample. Of course, if anybody else can provide such an example before I can get to it, that'd be great!

    FWIW, I've heard your cries to open up SignedRequestDecoder as public. If I do nothing else, I'll give that some consideration very soon. Know, however, that the reason I left it package private is because the *real* intended way of using it was via the @SignedRequest annotation in a Spring MVC controller. Using that annotation, you shouldn't need to use SignedRequestDecoder directly. Nevertheless, I see some value in exposing SignedRequestDecoder as public (in that it could come in handy for non-Spring MVC apps...perhaps in a Struts app), so I'll consider opening it up as public later today.
    Craig Walls
    Spring Social Project Lead

  4. #14
    Join Date
    Aug 2004
    Posts
    1,072

    Default

    blandger: If you cook up an Facebook Canvas example showcasing Spring Social, Thymeleaf, Mongo, etc. that'd be awesome! It wouldn't be the get-started-quickly kind of example, but I'm sure a lot of people would learn a lot from it.

    Of course, if there's anything that you think needs to happen to Spring Social or any of the extension libraries to support your example, feel free to open an improvement issue in Jira. I don't automatically implement all requests, but I won't know what you need if you don't ask.
    Craig Walls
    Spring Social Project Lead

  5. #15
    Join Date
    Jan 2013
    Posts
    7

    Default

    Quote Originally Posted by blandger View Post
    ... There are only two people who could give good advises and allow borrow they code: Craig and Yuan Ji ( www.jiwhiz.com )
    It is like quantum mechanics then

  6. #16

    Default

    Hi all.

    I caught a flu last time I wrote here on forum, so I spent all that time in bed with medicine. Tomorrow I start my work although I'm a weak and not fully recovered after flue.

    Quote Originally Posted by habuma View Post
    ........reason I left it package private is because the *real* intended way of using it was via the @SignedRequest annotation in a Spring MVC controller. Using that annotation, you shouldn't need to use SignedRequestDecoder directly. Nevertheless, I see some value in exposing SignedRequestDecoder as public (in that it could come in handy for non-Spring MVC apps...perhaps in a Struts app), so I'll consider opening it up as public later today.
    I tried using that parameter, but that didn't work for me. May be I've made something not quite correct, but that didn't work. The working option was explicitly extract parameter 'signed_request' directly from request.
    Best regards.

  7. #17
    Join Date
    Aug 2004
    Posts
    1,072

    Default

    FWIW, there's a brand new Spring Social Canvas sample out at https://github.com/SpringSource/spri...-social-canvas. While I was working on this, I found myself writing a lot of boilerplate code in something that ended up being named CanvasSignInController. After stripping it down to nothing but boilerplate code, I moved it into Spring Social Facebook's Web module so that everyone can benefit from it.

    Essentially, CanvasSignInController does the heavy lifting of receiving and decoding the signed_request parameter and from it extracting an access token and creating a connection. If no access token exists in the signed_request parameter, then it redirects to the Facebook authorization dialog. Upon returning, there should be an access token in the signed_request.

    Have a look at the new canvas sample to see how it can be done. But be aware that since I moved CanvasSignInController into the Spring Social Facebook Web module, there's not much to see in the sample application code itself (which is a good thing). The real work is now in framework code.
    Craig Walls
    Spring Social Project Lead

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •