javaspring-boottwitterjwtspring-social-twitter

How to integrate Twitter Login using JWT?


I have some application that works with Spring Boot. This is just login/registration page nothing more.

Start Login Register

My JWT Filter

public class JWTFilter extends GenericFilterBean {

    private static final String AUTHORIZATION_HEADER = "X-CustomToken";
    private static final String AUTHORITIES_KEY = "roles";

    /**
     * doFilter method for creating correct token(Bearer has taken from front-end part)
     *
     * @param req
     * @param res
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String authHeader = request.getHeader(AUTHORIZATION_HEADER);
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Authorization header.");
        } else {
            try {
                String token = authHeader.substring(7);
                Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
                request.setAttribute("claims", claims);
                SecurityContextHolder.getContext().setAuthentication(getAuthentication(claims));
                filterChain.doFilter(req, res);
            } catch (SignatureException e) {
                ((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
            }

        }
    }

    /**
     * Method for creating Authentication for Spring Security Context Holder
     * from JWT claims
     */
    private Authentication getAuthentication(Claims claims) {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        List<String> roles = (List<String>) claims.get(AUTHORITIES_KEY);
        for (String role : roles) {
            authorities.add(new SimpleGrantedAuthority(role));
        }
        User principal = new User(claims.getSubject(), "", authorities);
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                principal, "", authorities);
        return usernamePasswordAuthenticationToken;
    }
}

My WebSecurityConfig class

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * This method is for overriding some configuration of the WebSecurity
     * If you want to ignore some request or request patterns then you can
     * specify that inside this method
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
                // ignoring the "/index.html", "/app/**", "/registration",
                // "/favicon.ico"
                .antMatchers("/", "/index.html", "/app/**", "/registration", "/login", "/favicon.ico ", "/confirmRegistration/**")
                .and();
                }

    /**
     * This method is used for override HttpSecurity of the web Application.
     * We can specify our authorization criteria inside this method.
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .anyRequest().fullyAuthenticated().and()
                .addFilterBefore(new JWTFilter(), UsernamePasswordAuthenticationFilter.class)
                .httpBasic().and()
                .csrf().disable();
    }
}

So I have 1 admin hardcoded in data.sql and every user that registers in my app will get User role and save into MySQL. I'd like to add Social Apps Login (such as Twitter, Facebook and Google). The question is how to do that, if I use JWT? As far as I know, Oauth2 is preferable to use social apps, but can I do it in my way?

If I want to start with Twitter, how to do it best?

  1. Get consumer and secret keys from twitter API
  2. Put it into application.properties
  3. Set spring-social dependecies
  4. Create SocialConfig class
  5. Change my html login page file

So, do I need to change my login controller class?


Solution

  • I'm not sure about other social networks, but, if your code is Java and you are planning to work with the Twitter API, the way to go is using the Twitter4J library. It's a de-facto standard in the Java world, and is well documented.

    Sure, you need a Twitter Dev Account.You can get more info on the Twitter Dev Portal