-
Notifications
You must be signed in to change notification settings - Fork 526
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Authentication and Authorization
- Loading branch information
1 parent
c692aaf
commit 5d4593b
Showing
22 changed files
with
298 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
starter_code/src/main/java/com/example/demo/security/JWTAuthenticationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package com.example.demo.security; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Date; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import com.auth0.jwt.algorithms.Algorithm; | ||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.example.demo.model.persistence.User; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import static com.auth0.jwt.algorithms.Algorithm.HMAC512; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.Date; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.AuthenticationException; | ||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||
|
||
import com.auth0.jwt.JWT; | ||
import com.example.demo.model.persistence.User; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
|
||
import static com.auth0.jwt.algorithms.Algorithm.HMAC512; | ||
|
||
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { | ||
|
||
private AuthenticationManager authenticationManager; | ||
|
||
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { | ||
this.authenticationManager = authenticationManager; | ||
} | ||
|
||
@Override | ||
public Authentication attemptAuthentication(HttpServletRequest req, | ||
HttpServletResponse res) throws AuthenticationException { | ||
try { | ||
User credentials = new ObjectMapper() | ||
.readValue(req.getInputStream(), User.class); | ||
|
||
return authenticationManager.authenticate( | ||
new UsernamePasswordAuthenticationToken( | ||
credentials.getUsername(), | ||
credentials.getPassword(), | ||
new ArrayList<>())); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
protected void successfulAuthentication(HttpServletRequest req, | ||
HttpServletResponse res, | ||
FilterChain chain, | ||
Authentication auth) throws IOException, ServletException { | ||
|
||
String token = JWT.create() | ||
.withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername()) | ||
.withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME)) | ||
.sign(HMAC512(SecurityConstants.SECRET.getBytes())); | ||
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
starter_code/src/main/java/com/example/demo/security/JWTAuthenticationVerficationFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.example.demo.security; | ||
|
||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
import org.springframework.security.authentication.AuthenticationManager; | ||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; | ||
import org.springframework.stereotype.Component; | ||
|
||
import com.auth0.jwt.JWT; | ||
|
||
import static com.auth0.jwt.algorithms.Algorithm.HMAC512; | ||
|
||
@Component | ||
public class JWTAuthenticationVerficationFilter extends BasicAuthenticationFilter { | ||
|
||
public JWTAuthenticationVerficationFilter(AuthenticationManager authManager) { | ||
super(authManager); | ||
} | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) | ||
throws IOException, ServletException { | ||
String header = req.getHeader(SecurityConstants.HEADER_STRING); | ||
|
||
if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) { | ||
chain.doFilter(req, res); | ||
return; | ||
} | ||
|
||
UsernamePasswordAuthenticationToken authentication = getAuthentication(req); | ||
|
||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
chain.doFilter(req, res); | ||
} | ||
|
||
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) { | ||
String token = req.getHeader(SecurityConstants.HEADER_STRING); | ||
if (token != null) { | ||
String user = JWT.require(HMAC512(SecurityConstants.SECRET.getBytes())).build() | ||
.verify(token.replace(SecurityConstants.TOKEN_PREFIX, "")) | ||
.getSubject(); | ||
if (user != null) { | ||
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>()); | ||
} | ||
return null; | ||
} | ||
return null; | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
starter_code/src/main/java/com/example/demo/security/SecurityConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.example.demo.security; | ||
|
||
public class SecurityConstants { | ||
|
||
public static final String SECRET = "oursecretkey"; | ||
public static final long EXPIRATION_TIME = 864_000_000; // 10 days | ||
public static final String TOKEN_PREFIX = "Bearer "; | ||
public static final String HEADER_STRING = "Authorization"; | ||
public static final String SIGN_UP_URL = "/api/user/create"; | ||
} |
28 changes: 28 additions & 0 deletions
28
starter_code/src/main/java/com/example/demo/security/UserDetailsServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.example.demo.security; | ||
|
||
import java.util.Collections; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.security.core.userdetails.UserDetails; | ||
import org.springframework.security.core.userdetails.UserDetailsService; | ||
import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||
import org.springframework.stereotype.Service; | ||
|
||
import com.example.demo.model.persistence.User; | ||
import com.example.demo.model.persistence.repositories.UserRepository; | ||
|
||
@Service | ||
public class UserDetailsServiceImpl implements UserDetailsService { | ||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
@Override | ||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||
User user = userRepository.findByUsername(username); | ||
if (user == null) { | ||
throw new UsernameNotFoundException(username); | ||
} | ||
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), Collections.emptyList()); | ||
} | ||
} |
Oops, something went wrong.