spring-boottwitterspring-socialspring-social-twitter

Twitter Sign in using Spring Boot


I am trying to sign in to my web application (developed using Spring Boot) using social logins. The logins for Google & facebook are okay. But the for some reason there is a token issue in the twitter login. I have created the project in the twitter developer site obtained all the credentials. Please refer to my code below.

My Property file values are mentioned below.

twitter.client.client-id=XXXXXXX

twitter.client.client-secret=XXXXXXXX

twitter.client.access-token-uri=https://api.twitter.com/oauth/access_token

twitter.client.user-authorization-uri=https://api.twitter.com/oauth/authorize

twitter.client.token-name=oauth_token

twitter.client.authentication-scheme=form

twitter.resource.user-info-uri=https://api.twitter.com/1.1/account/verify_credentials.json

The filter method

private Filter ssoTwitterFilter(String processingUrl, PrincipalExtractor principalExtractor) {
    OAuth2ClientAuthenticationProcessingFilter twitterFilter = new OAuth2ClientAuthenticationProcessingFilter(
            processingUrl);
    LOGGER.debug("processingUrl :{} ", processingUrl);

    twitterFilter.setAuthenticationSuccessHandler(authenticationSuccessHandlerAndRegistrationFilter());
    OAuth2RestTemplate twitterTemplate = new OAuth2RestTemplate(twitter(), oauth2ClientContext);
    twitterFilter.setRestTemplate(twitterTemplate);
    UserInfoTokenServices tokenServices = new UserInfoTokenServices(twitterResource().getUserInfoUri(),
            twitter().getClientId());
    tokenServices.setRestTemplate(twitterTemplate);
    tokenServices.setPrincipalExtractor(principalExtractor);
    return twitterFilter;
}

These are the bean configurations.

@Bean
@ConfigurationProperties("twitter.client")
public AuthorizationCodeResourceDetails twitter() {
    return new AuthorizationCodeResourceDetails();
}

@Bean
@ConfigurationProperties("twitter.resource")
public ResourceServerProperties twitterResource() {
    return new ResourceServerProperties();
}

This is the error that I get enter image description here

Please can anyone shed some light on this. Because all the samples I found were related getting profile information from twitter where as i need a sample for sign in using spring Boot. Thanks in advance


Solution

  • You can configure Twitter login like this:

     @Configuration
     @EnableSocial
    public class SocialConfig implements SocialConfigurer {
    
    @Autowired
    private  UserAuthorizationService userAuthorizationService;
    @Override
    public void addConnectionFactories(ConnectionFactoryConfigurer cfConfig, Environment env) {
    
        cfConfig.addConnectionFactory(new TwitterConnectionFactory(
                env.getProperty("twitter.consumer-key"),
                env.getProperty("twitter.consumer-secret")
        ));
    
    
    
    }
    
    @Override
    public UserIdSource getUserIdSource() {
        return new UserIdSource() {
            @Override
            public String getUserId() {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication == null) {
                    throw new IllegalStateException("Unable to get a ConnectionRepository: no user signed in");
                }
                return authentication.getName();
            }
        };
    }
    
    
    @Override
    public UsersConnectionRepository getUsersConnectionRepository(ConnectionFactoryLocator connectionFactoryLocator) {
        InMemoryUsersConnectionRepository usersConnectionRepository = new InMemoryUsersConnectionRepository(
    
                connectionFactoryLocator
        );
        return usersConnectionRepository;
    }
    
    
    @Autowired
    private TwitterConnectionSignup twitterConnectionSignup;
    @Autowired
    private ConnectionFactoryLocator connectionFactoryLocator;
    
    @Autowired
    private UsersConnectionRepository usersConnectionRepository;
    @Bean
    public ProviderSignInController providerSignInController() {
        ((InMemoryUsersConnectionRepository) usersConnectionRepository)
                .setConnectionSignUp(twitterConnectionSignup);
    
        return new ProviderSignInController(
                connectionFactoryLocator,
                usersConnectionRepository,
                new TwitterSignInAdapter(userAuthorizationService));
    }
    

    }

    Configure TwitterConnectionSignup:

    @Service
    public class TwitterConnectionSignup implements ConnectionSignUp {
    
    @Autowired
    private UserRepo userRepo;
    
    @Override
    public String execute(Connection<?> connection) {
    
       //add your logic to save user to your db
        return connection.getDisplayName();
    }
    

    }

    Now configure TwitterSignInAdapter:

    public class TwitterSignInAdapter implements SignInAdapter {
    private UserAuthorizationService userAuthorizationService;
    
    public TwitterSignInAdapter(UserAuthorizationService userAuthorizationService) {
        this.userAuthorizationService = userAuthorizationService;
    }
    
    @Override
    public String signIn(String localUserId, Connection<?> connection, NativeWebRequest webRequest) {
    
        log.debug(" Email {}", localUserId);
    
        UserAuthDto userAuthDto = (UserAuthDto) userAuthorizationService.loadUserByUsername(localUserId);
        UsernamePasswordAuthenticationToken updatedAuth = new UsernamePasswordAuthenticationToken(userAuthDto, userAuthDto.getSocialId(),
                userAuthDto.getAuthorities());
    
    
        SecurityContextHolder.getContext().setAuthentication(updatedAuth);
        HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        // add authentication to the session
        servletRequest.getSession().setAttribute(
                HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
                SecurityContextHolder.getContext());
    
    
        return "/";
    }
    

    }