I have some application that works with Spring Boot. This is just login/registration page nothing more.
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?
So, do I need to change my login controller class?
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