Page 1 of 2 12 LastLast
Results 1 to 10 of 18

Thread: 400 Bad Request

  1. #1

    Default 400 Bad Request

    Hi,

    I have tried to connect to Facebook with Spring Social but it didn't work - I always get this exception trace above.
    Does anybody know what I' am doing wrong? The accessToken is the right one, also appl ID. Secret Key is faced.
    Thanks a lot for help!
    Generic1

    org.springframework.web.util.NestedServletExceptio n: Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorExce ption: 400 Bad Request
    org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:681)
    org.springframework.web.servlet.FrameworkServlet.d oGet(FrameworkServlet.java:574)
    javax.servlet.http.HttpServlet.service(HttpServlet .java:617)
    javax.servlet.http.HttpServlet.service(HttpServlet .java:717)

    root cause

    org.springframework.web.client.HttpClientErrorExce ption: 400 Bad Request
    org.springframework.web.client.DefaultResponseErro rHandler.handleError(DefaultResponseErrorHandler.j ava:75)
    org.springframework.web.client.RestTemplate.handle ResponseError(RestTemplate.java:486)
    org.springframework.web.client.RestTemplate.doExec ute(RestTemplate.java:443)
    org.springframework.web.client.RestTemplate.execut e(RestTemplate.java:401)
    org.springframework.web.client.RestTemplate.postFo rObject(RestTemplate.java:279)
    org.springframework.social.facebook.connect.Facebo okOAuth2Template.postForAccessGrant(FacebookOAuth2 Template.java:57)
    org.springframework.social.oauth2.OAuth2Template.e xchangeForAccess(OAuth2Template.java:104)
    at.eventtiming.frontend.controller.HomeController. handle(HomeController.java:40)
    Code:
    public final class HomeController {
    
        public HomeController() {}
    
        @RequestMapping("/index")
        public String handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
            FacebookConnectionFactory connectionFactory = new FacebookConnectionFactory("338138429607553", "acafxxxxxxxxxb713200ffa81081");
            OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
            OAuth2Parameters params = new OAuth2Parameters();
            params.setRedirectUri("http://localhost:8080/JSPTest/index.htm");
            String authorizeUrl = oauthOperations.buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, params);
            System.out.println("authorizeUrl: " + authorizeUrl);
            response.sendRedirect(authorizeUrl);
            String accessToken = "AAAEziPz7ToEBAHsiLzF4GAte8oGa7lFTbzuRoZBzMubg2gfNSt0K2DS72sQSRmyRCVhRDjmmV4QWcFZCjTn6XPqsVIHltc1LpZA0kmJ2VxSYVw1TuwN";
    
            // upon receiving the callback from the provider:
            AccessGrant accessGrant = oauthOperations.exchangeForAccess(accessToken, "http://localhost:8080/JSPTest/index.htm", null);
            Connection<Facebook> connection = connectionFactory.createConnection(accessGrant);
            return "home";
            }
    }

  2. #2
    Join Date
    Aug 2004
    Posts
    1,070

    Default

    It's clear from looking at this that you're misusing exchangeForAccess(). The proper way to use that method is to exchange an authorization code for an access grant (which contains the access token value). But it looks like you're trying to exchange an access token for an access token, which isn't correct.

    What is supposed to happen is that you redirect your user's browser to the authorization URL where they will accept or deny authorization. Assuming that they accept, then Facebook will redirect them back to your application with an authorization code as a query parameter. It's this authorization code that you pass to exchangeForAccess() to get an access token (and then you can create a connection, use the token to access the API, or whatever it is you'd like to do.

    What puzzles me more, however, is why you're trying to implement the OAuth2 authorization flow with Facebook when Spring Social already implements that with ConnectController? Everything that it appears that you're trying to do in HomeController is already handled by ConnectController for you, so why not use that?
    Craig Walls
    Spring Social Project Lead

  3. #3

    Default

    Hi,
    Thanks a lot for your help - I was not sure about ConnectController does all the things. I read a tutorial where it was explained like I did above.
    Now I have tried to create my example like in this tutorialhttp://static.springsource.org/sprin...onnecting.html
    but I have still some problems.
    The ControllerConnection- Controller isn't invoked after clicking the login- button - I get a HTTP 404 code - the ConnectionController for /connect/twitter can't be found.
    For me it is not clear where I have made the fault - at the ViewResolver or the Spring Social config.
    Here my ViewResolver:
    HTML Code:
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
         </bean>
    and here my Spring Social config:

    HTML Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:jdbc="http://www.springframework.org/schema/jdbc"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd">
    
          <jdbc:embedded-database id="dataSource" type="H2">
    		<jdbc:script location="classpath:/org/springframework/social/connect/jdbc/JdbcUsersConnectionRepository.sql" />
          </jdbc:embedded-database>
    
          <bean id="connectionFactoryLocator" class="org.springframework.social.connect.support.ConnectionFactoryRegistry">
                <property name="connectionFactories">
                    <list>
                        <bean class="org.springframework.social.twitter.connect.TwitterConnectionFactory">
                            <constructor-arg value="JB7veSg6Bxxxxxxxxxng" />
                            <constructor-arg value="D9fKgpHjUq6yfffffffffffffffD0fjaBu1HcvKsesk" />
                        </bean>
                    </list>
                </property>
            </bean>
    
            <bean id="usersConnectionRepository" class="org.springframework.social.connect.jdbc.JdbcUsersConnectionRepository">
                <constructor-arg ref="dataSource" />
                <constructor-arg ref="connectionFactoryLocator" />
                <constructor-arg ref="textEncryptor" />
            </bean>
    
            <bean id="connectionRepository" factory-method="createConnectionRepository"
                  factory-bean="usersConnectionRepository" scope="request">
                <constructor-arg value="#{request.userPrincipal.name}" />
                <aop:scoped-proxy proxy-target-class="false" />
            </bean>
    
          <bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors" factory-method="noOpText" />
    
            <bean class="org.springframework.social.connect.web.ConnectController">
                <constructor-arg ref="connectionFactoryLocator" />
                <constructor-arg ref="connectionRepository" />
                <!--<property name="applicationUrl" value="http://localhost:8080/JSPTest/connect/twitter" />-->
            </bean>
    
    </beans>
    I have read your posts from http://forum.springsource.org/archiv.../t-105079.html but I couldn't solve it.

    Maybe you have a hint what I can do in order to get it work.
    Thanks a lot for your help!
    Generic





    I have also uploaded my simple small poject at http://www.file-upload.net/download-...PTest.zip.html.

  4. #4

    Default

    I can't belief it but it works :-) I had to add

    <context:component-scan base-package="org.springframework.social.connect.web">
    <context:exclude-filter type="regex" expression="org.springframework.social.connect.web .ProviderSignInController"/>
    </context:component-scan>

    ,then it worked.

    Whats still not clear for me is, where I can change the redirect- URL for Twitter. Now I had to make the structure WEB-INF/jsp/connect/twitterConnected.jsp and there I am redirected after login at twitter. But the redirection for my application should be WEB-INF/jsp/home.jsp.
    Is there a possibility to redirect to my home.jsp?

    And I would have a further question: before the redirection, where can I get the Twitter- API to set the Name and Profile- image into the session of my web application in order to show the name und profile image after login?

    Thanks a lot for your help!!
    Generic

  5. #5
    Join Date
    Aug 2004
    Posts
    1,070

    Default

    I'm glad you got it to work, but...you could've accomplished the same thing without component-scanning and simply explicitly configuring ConnectController. That's how all of the samples at https://github.com/SpringSource/spring-social-samples do it. And if you explicitly configure it, then you don't have to exclude ProviderSignInController.

    As for the redirect: It *must* come back to ConnectController so that ConnectController can exchange the authorization code/verifier for an access token and complete the connection. And, ConnectController then sends the request to the view whose logical view name is "connect/{provider name}Connected"...in your case that is WEB-INF/jsp/connect/twitterConnected.jsp. You can make it go to any view you want, however, by subclassing ConnectController and overriding the connectView() method to return whatever view name you want (you can even use a "redirect:" prefix to do a redirect if you'd like...for example, it could return "redirect:/home").
    Craig Walls
    Spring Social Project Lead

  6. #6

    Default

    Thanks once more. It works fine. My overridden ConnectController now look like this:

    Code:
    package at.company.frontend.controller;
    
    import javax.inject.Inject;
    import org.springframework.social.connect.ConnectionFactoryLocator;
    import org.springframework.social.connect.ConnectionRepository;
    import org.springframework.social.connect.web.ConnectController;
    import org.springframework.social.connect.web.ConnectInterceptor;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.context.request.NativeWebRequest;
    import org.springframework.web.servlet.view.RedirectView;
    
    @Controller
    public class MyConnectController extends ConnectController {
    
        @Inject
        public AtleticusConnectController(ConnectionFactoryLocator connectionFactoryLocator, ConnectionRepository connectionRepository) {
            super(connectionFactoryLocator, connectionRepository);
            ConnectInterceptor ci = new MyTwitterConnectInterceptor();
            super.addInterceptor(ci);
            }
        
        @Override
        public RedirectView oauth1Callback(String providerId, NativeWebRequest nwr) {
            return super.oauth1Callback(providerId, nwr);
    	}
    
        @Override
        public String connectView(String id) {
            super.connectView(id);
            return "redirect:/home.htm";
            }
    }
    The only thing what isn't working is, the MyTwitterConnectInterceptor#postConnect method isn't invoked (preConnect is invoked as expected) and I get a Warning:

    WARNUNG: Exception while handling OAuth1 callback (No connection factory for service provider 'null' is registered). Redirecting to null connection status page.

    If I don't override oauth1Callback, postConnect is invoked but I will be redirected to the standard redirection- page /jsp/connect/twitterConnected.jsp.

    Maybe you can help me once again.
    Thanks a lot.
    Generic

  7. #7
    Join Date
    Aug 2004
    Posts
    1,070

    Default

    What's the URL when handling the redirect? Its path should be /connect/twitter. If it's not, then what is it? Is it /connect/null? If so, I feel like I'm missing something from your config that would explain this.
    Craig Walls
    Spring Social Project Lead

  8. #8

    Default

    I have made a workaround that works for me:

    @Override
    public RedirectView oauth1Callback(String providerId, NativeWebRequest nwr) {
    super.oauth1Callback("twitter", nwr);
    return new RedirectView("/twitter.hml", true);
    }

    Actually I don't know why providerId is null. I havn't intentionally configured something in order that providerId is null.

    I have uploaded once again my current Version (I use Netbeans as ID). Maybe someone has the delight to throw a glance over it.
    Thanks!!
    Generic

    http://www.file-upload.net/download-...PTest.zip.html

  9. #9
    Join Date
    Oct 2011
    Location
    London, UK
    Posts
    27

    Default

    I had a look at your code earlier and couldn't spot what was wrong, but I think I've just realised what's missing - it's the @PathVariable annotation before the providerId parameter in the method signature.

    Your overridden method should be:

    @Override
    public RedirectView oauth1Callback(@PathVariable String providerId, NativeWebRequest nwr) {
    return super.oauth1Callback(providerId, nwr);
    }

    This will allow spring mvc to set the providerId based on the callback path.

  10. #10
    Join Date
    Oct 2011
    Location
    London, UK
    Posts
    27

    Default

    Just to add to my previous comment.. while I believe adding the @PathVariable to the overridden callback method will resolve this issue, I'm not sure you need to be overriding this method at all.

    To override the default status views you should only need override the connectView methods. I've just tried a simple local example - subclassing ConnectController with these methods overridden and the app respected these overrides and redirected to my custom views. I also had a ConnectInterceptor wired in whose postConnect method was called, so you shouldn't need to override the callback for this reason.

    I may have missed something here, there may be something else in your setup which means you'd like to override the callback method, but in theory you shouldn't need to.

    Hope this helps,

    Michael

Posting Permissions

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