-
Notifications
You must be signed in to change notification settings - Fork 9
43 add security compatibility #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
43 add security compatibility #57
Conversation
…yeredd/interview-evaluations into 43-add-security-compatibility
|
|
||
| @EnableJpaRepositories(basePackageClasses=PersonRepository.class) | ||
| @SpringBootApplication | ||
| public class InterviewEvaluationsApplication { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
@tjkemper please review this. |
|
This is a lot in one PR. Initial reactions
|
|
Claims have a secret: mySecret (see application.yml and JwtTokenUtil) |
… extra to be discarded when external token generation/validation is implemented
| private UserRepository userRepository; | ||
|
|
||
| @Override | ||
| public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| private final boolean enabled; | ||
| private final Date lastPasswordResetDate; | ||
|
|
||
| public JwtUser( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| audience = (String) claims.get(CLAIM_KEY_AUDIENCE); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Date expires; | ||
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| expires = claims.getExpiration(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| expires = claims.getExpiration(); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Date created; | ||
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| created = new Date((Long) claims.get(CLAIM_KEY_CREATED)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| created = new Date((Long) claims.get(CLAIM_KEY_CREATED)); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| String refreshedToken; | ||
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| claims.put(CLAIM_KEY_CREATED, new Date()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| .setSigningKey(secret) | ||
| .parseClaimsJws(token) | ||
| .getBody(); | ||
| } catch (ExpiredJwtException | MalformedJwtException | SignatureException | UnsupportedJwtException | IllegalArgumentException e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| final Claims claims = getClaimsFromToken(token); | ||
| claims.put(CLAIM_KEY_CREATED, new Date()); | ||
| refreshedToken = generateToken(claims); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| String username; | ||
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| username = claims.getSubject(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| username = claims.getSubject(); | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| String audience; | ||
| try { | ||
| final Claims claims = getClaimsFromToken(token); | ||
| audience = (String) claims.get(CLAIM_KEY_AUDIENCE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tjkemper
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall good progress.
Focus on verifying the JWT has the correct signature.
The API does not need to worry about usernames/passwords or generating tokens.
| authReq.getPassword()) | ||
| ); | ||
|
|
||
| SecurityContextHolder.getContext().setAuthentication(authentication); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid using SecurityContext. We want our API to be stateless.
| private String tokenHeader; | ||
|
|
||
| @Override | ||
| protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're on the right track here.
May want something like:
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);
//OK, we can trust this JWT
} catch (SignatureException e) {
//don't trust the JWT!
}
Notice we do not know anything about the user. We only care that the JWT was signed with our secret and it wasn't tampered with.
…cation to new project
|
Build fails for non-existent dependency (JwtAuthenticationFilter [8,37]) The dependency is a local second project. The dependency is in the POM and the directory is in the classpath. Any ideas as to why it can't find this dependency would be appreciated. POM: Classpath: |
…are to be removed and placed in a seperate Authorization Server service. All files in the 'static' folder likewise belong to the future Authorization Server service
|
|
||
| String token = req.getHeader(tokenHeader); | ||
| String username = jwtTokenUtil.getUsernameFromToken(token); | ||
| JwtUser user = (JwtUser) userDetailsService.loadUserByUsername(username); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| //This value can be found in the application.yml file | ||
| @RequestMapping(value = "${jwt.route.authentication.path}", method = RequestMethod.POST) | ||
| public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authReq, Device dev) throws AuthenticationException{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| //This value can be found in the application.yml file | ||
| @RequestMapping(value = "${jwt.route.authentication.refresh}", method = RequestMethod.GET) | ||
| public ResponseEntity<?> refreshAndGetAuthenticationToken(HttpServletRequest req){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…yeredd/interview-evaluations into 43-add-security-compatibility



Security compatibility using JWT.
Temporary token generator/validator is JwtTokenUtil.
Security classes (by package):
com.revature.config: WebSecurityConfig
com.revature.repositories: UserRepository
com.revature.model.security: Authority, AuthorityName, User
com.revature.security: JwtAuthenticationEntryPoint, JwtAuthenticationFilter, JwtAuthenticationRequest, JwtAuthenticationSuccessHandler, JwtTokenUtil (TEMP), JwtUser, JwtUserFactory
com.revature.security.controllers: AuthenticationRestController, UserRestController
com.revature.security.exceptions: JwtTokenMissingException
com.revature.security.service: JwtAuthenticationResponse, JwtUserDetailsServiceImpl