· 5 years ago · Nov 25, 2019, 03:04 PM
1public class JwtRequestFilter extends OncePerRequestFilter {
2
3 @Autowired
4 private MyUserDetailsService userDetailsService;
5
6 @Autowired
7 private JwtUtil jwtUtil;
8
9 @Override
10 protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
11 throws ServletException, IOException {
12
13 final String authorizationHeader = request.getHeader("Authorization");
14
15 String username = null;
16 String jwt = null;
17
18 if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
19 jwt = authorizationHeader.substring(7);
20 username = jwtUtil.extractUsername(jwt);
21 }
22
23
24 if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
25
26 UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
27
28 if (jwtUtil.validateToken(jwt, userDetails)) {
29
30 UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
31 userDetails, null, userDetails.getAuthorities());
32 usernamePasswordAuthenticationToken
33 .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
34 SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
35 }
36 }
37 chain.doFilter(request, response);
38 }
39
40}
41
42public class AuthenticationRequest implements Serializable {
43
44
45 private String username;
46 private String password;
47
48 public String getUsername() {
49 return username;
50 }
51
52 public void setUsername(String username) {
53 this.username = username;
54 }
55
56 public String getPassword() {
57 return password;
58 }
59
60 public void setPassword(String password) {
61 this.password = password;
62 }
63
64 //need default constructor for JSON Parsing
65 public AuthenticationRequest()
66 {
67
68 }
69
70 public AuthenticationRequest(String username, String password) {
71 this.setUsername(username);
72 this.setPassword(password);
73 }
74}
75
76public class AuthenticationResponse implements Serializable {
77
78 private final String jwt;
79
80 public AuthenticationResponse(String jwt) {
81 this.jwt = jwt;
82 }
83
84 public String getJwt() {
85 return jwt;
86 }
87}
88
89public class JwtUtil {
90
91 private String SECRET_KEY = "secret";
92
93 public String extractUsername(String token) {
94 return extractClaim(token, Claims::getSubject);
95 }
96
97 public Date extractExpiration(String token) {
98 return extractClaim(token, Claims::getExpiration);
99 }
100
101 public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
102 final Claims claims = extractAllClaims(token);
103 return claimsResolver.apply(claims);
104 }
105 private Claims extractAllClaims(String token) {
106 return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
107 }
108
109 private Boolean isTokenExpired(String token) {
110 return extractExpiration(token).before(new Date());
111 }
112
113 public String generateToken(UserDetails userDetails) {
114 Map<String, Object> claims = new HashMap<>();
115 return createToken(claims, userDetails.getUsername());
116 }
117
118 private String createToken(Map<String, Object> claims, String subject) {
119
120 return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
121 .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10))
122 .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
123 }
124
125 public Boolean validateToken(String token, UserDetails userDetails) {
126 final String username = extractUsername(token);
127 return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
128 }
129}
130
131public class MyUserDetailsService implements UserDetailsService {
132
133 @Override
134 public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
135 return new User("foo", "foo",
136 new ArrayList<>());
137 }
138}
139
140@SpringBootApplication
141public class SpringSecurityJwtApplication {
142
143 public static void main(String[] args) {
144 SpringApplication.run(SpringSecurityJwtApplication.class, args);
145 }
146
147}
148
149@RestController
150class HelloWorldController {
151
152 @Autowired
153 private AuthenticationManager authenticationManager;
154
155 @Autowired
156 private JwtUtil jwtTokenUtil;
157
158 @Autowired
159 private MyUserDetailsService userDetailsService;
160
161 @RequestMapping({ "/hello" })
162 public String firstPage() {
163 return "Hello World";
164 }
165
166 @RequestMapping(value = "/authenticate", method = RequestMethod.POST)
167 public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
168
169 try {
170 authenticationManager.authenticate(
171 new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
172 );
173 }
174 catch (BadCredentialsException e) {
175 throw new Exception("Incorrect username or password", e);
176 }
177
178
179 final UserDetails userDetails = userDetailsService
180 .loadUserByUsername(authenticationRequest.getUsername());
181
182 final String jwt = jwtTokenUtil.generateToken(userDetails);
183
184 return ResponseEntity.ok(new AuthenticationResponse(jwt));
185 }
186
187}
188
189@EnableWebSecurity
190class WebSecurityConfig extends WebSecurityConfigurerAdapter {
191 @Autowired
192 private UserDetailsService myUserDetailsService;
193 @Autowired
194 private JwtRequestFilter jwtRequestFilter;
195
196 @Autowired
197 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
198 auth.userDetailsService(myUserDetailsService);
199 }
200
201 @Bean
202 public PasswordEncoder passwordEncoder() {
203 return NoOpPasswordEncoder.getInstance();
204 }
205
206 @Override
207 @Bean
208 public AuthenticationManager authenticationManagerBean() throws Exception {
209 return super.authenticationManagerBean();
210 }
211
212 @Override
213 protected void configure(HttpSecurity httpSecurity) throws Exception {
214 httpSecurity.csrf().disable()
215 .authorizeRequests().antMatchers("/authenticate").permitAll().
216 anyRequest().authenticated().and().
217 exceptionHandling().and().sessionManagement()
218 .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
219 httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
220
221 }
222
223}