├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── jwtme │ │ ├── JwtmeApplication.java │ │ ├── controllers │ │ └── UserController.java │ │ └── security │ │ ├── AccountCredentials.java │ │ ├── JWTAuthenticationFilter.java │ │ ├── JWTLoginFilter.java │ │ ├── TokenAuthenticationService.java │ │ └── WebSecurityConfig.java └── resources │ └── application.properties └── test └── java └── com └── jwtme └── JwtmeApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreybleme/jwt-me/f4c62e0de61bf8cd08dda1f6f3fae77d8471e16e/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jwt-me 2 | This is a JWT authentication sample, implemented using Spring Boot. 3 | 4 | A complete guide can be found on [http://andreybleme.com/2017-04-01/autenticacao-com-jwt-no-spring-boot/](http://andreybleme.com/2017-04-01/autenticacao-com-jwt-no-spring-boot/) 5 | 6 | 7 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.jwtme 7 | jwtme 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | jwtme 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 1.5.2.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-security 42 | 43 | 44 | 45 | io.jsonwebtoken 46 | jjwt 47 | 0.7.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/JwtmeApplication.java: -------------------------------------------------------------------------------- 1 | package com.jwtme; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | @SpringBootApplication 10 | @RestController 11 | public class JwtmeApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(JwtmeApplication.class, args); 15 | } 16 | 17 | @RequestMapping("/home") 18 | public String hello() { 19 | return "Hello buddy!"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/controllers/UserController.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.controllers; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.ResponseBody; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | public class UserController { 9 | 10 | @RequestMapping("/users") 11 | @ResponseBody 12 | public String getUsers() { 13 | return "{\"users\":[{\"name\":\"Lucas\", \"country\":\"Brazil\"}," + 14 | "{\"name\":\"Jackie\",\"country\":\"China\"}]}"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/security/AccountCredentials.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.security; 2 | 3 | public class AccountCredentials { 4 | 5 | private String username; 6 | private String password; 7 | 8 | public String getUsername() { 9 | return username; 10 | } 11 | 12 | public void setUsername(String username) { 13 | this.username = username; 14 | } 15 | 16 | public String getPassword() { 17 | return password; 18 | } 19 | 20 | public void setPassword(String password) { 21 | this.password = password; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/security/JWTAuthenticationFilter.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.security; 2 | 3 | import java.io.IOException; 4 | 5 | import javax.servlet.FilterChain; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.ServletRequest; 8 | import javax.servlet.ServletResponse; 9 | import javax.servlet.http.HttpServletRequest; 10 | 11 | import org.springframework.security.core.Authentication; 12 | import org.springframework.security.core.context.SecurityContextHolder; 13 | import org.springframework.web.filter.GenericFilterBean; 14 | 15 | public class JWTAuthenticationFilter extends GenericFilterBean { 16 | 17 | @Override 18 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) 19 | throws IOException, ServletException { 20 | 21 | Authentication authentication = TokenAuthenticationService 22 | .getAuthentication((HttpServletRequest) request); 23 | 24 | SecurityContextHolder.getContext().setAuthentication(authentication); 25 | filterChain.doFilter(request, response); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/security/JWTLoginFilter.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.security; 2 | 3 | import java.io.IOException; 4 | import java.util.Collections; 5 | 6 | import javax.servlet.FilterChain; 7 | import javax.servlet.ServletException; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | 11 | import org.springframework.security.authentication.AuthenticationManager; 12 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 13 | import org.springframework.security.core.Authentication; 14 | import org.springframework.security.core.AuthenticationException; 15 | import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; 16 | import org.springframework.security.web.util.matcher.AntPathRequestMatcher; 17 | 18 | import com.fasterxml.jackson.databind.ObjectMapper; 19 | 20 | public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter { 21 | 22 | protected JWTLoginFilter(String url, AuthenticationManager authManager) { 23 | super(new AntPathRequestMatcher(url)); 24 | setAuthenticationManager(authManager); 25 | } 26 | 27 | @Override 28 | public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) 29 | throws AuthenticationException, IOException, ServletException { 30 | 31 | AccountCredentials credentials = new ObjectMapper() 32 | .readValue(request.getInputStream(), AccountCredentials.class); 33 | 34 | return getAuthenticationManager().authenticate( 35 | new UsernamePasswordAuthenticationToken( 36 | credentials.getUsername(), 37 | credentials.getPassword(), 38 | Collections.emptyList() 39 | ) 40 | ); 41 | } 42 | 43 | @Override 44 | protected void successfulAuthentication( 45 | HttpServletRequest request, 46 | HttpServletResponse response, 47 | FilterChain filterChain, 48 | Authentication auth) throws IOException, ServletException { 49 | 50 | TokenAuthenticationService.addAuthentication(response, auth.getName()); 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/security/TokenAuthenticationService.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.security; 2 | 3 | import java.io.IOException; 4 | import java.util.Collections; 5 | import java.util.Date; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; 11 | import org.springframework.security.core.Authentication; 12 | 13 | import io.jsonwebtoken.Jwts; 14 | import io.jsonwebtoken.SignatureAlgorithm; 15 | 16 | public class TokenAuthenticationService { 17 | 18 | // EXPIRATION_TIME = 10 dias 19 | static final long EXPIRATION_TIME = 860_000_000; 20 | static final String SECRET = "MySecret"; 21 | static final String TOKEN_PREFIX = "Bearer"; 22 | static final String HEADER_STRING = "Authorization"; 23 | 24 | static void addAuthentication(HttpServletResponse response, String username) throws IOException { 25 | String JWT = Jwts.builder() 26 | .setSubject(username) 27 | .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) 28 | .signWith(SignatureAlgorithm.HS512, SECRET) 29 | .compact(); 30 | response.getWriter().write(JWT); 31 | } 32 | 33 | static Authentication getAuthentication(HttpServletRequest request) { 34 | String token = request.getHeader(HEADER_STRING); 35 | 36 | if (token != null) { 37 | // faz parse do token 38 | String user = Jwts.parser() 39 | .setSigningKey(SECRET) 40 | .parseClaimsJws(token.replace(TOKEN_PREFIX, "")) 41 | .getBody() 42 | .getSubject(); 43 | 44 | if (user != null) { 45 | return new UsernamePasswordAuthenticationToken(user, null, Collections.emptyList()); 46 | } 47 | } 48 | return null; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/jwtme/security/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.jwtme.security; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.http.HttpMethod; 5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 8 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 9 | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; 10 | 11 | @Configuration 12 | @EnableWebSecurity 13 | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 14 | 15 | @Override 16 | protected void configure(HttpSecurity httpSecurity) throws Exception { 17 | httpSecurity.csrf().disable().authorizeRequests() 18 | .antMatchers("/home").permitAll() 19 | .antMatchers(HttpMethod.POST, "/login").permitAll() 20 | .anyRequest().authenticated() 21 | .and() 22 | 23 | // filtra requisições de login 24 | .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), 25 | UsernamePasswordAuthenticationFilter.class) 26 | 27 | // filtra outras requisições para verificar a presença do JWT no header 28 | .addFilterBefore(new JWTAuthenticationFilter(), 29 | UsernamePasswordAuthenticationFilter.class); 30 | } 31 | 32 | @Override 33 | protected void configure(AuthenticationManagerBuilder auth) throws Exception { 34 | // cria uma conta default 35 | auth.inMemoryAuthentication() 36 | .withUser("admin") 37 | .password("password") 38 | .roles("ADMIN"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andreybleme/jwt-me/f4c62e0de61bf8cd08dda1f6f3fae77d8471e16e/src/main/resources/application.properties -------------------------------------------------------------------------------- /src/test/java/com/jwtme/JwtmeApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.jwtme; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class JwtmeApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------