UserLoginRequest
@Data
public class UserLoginRequest {
private String email;
private String password;
}
AuthenticationFilter
public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public AuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
try {
UserLoginRequest creds = new ObjectMapper()
.readValue(request.getInputStream(), UserLoginRequest.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
creds.getEmail(),
creds.getPassword(),
new ArrayList<>()
)
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
String username = ((User) authResult.getPrincipal()).getUsername();
String token = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SecurityConstants.TOKEN_SECRET)
.compact();
response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
}
}
User user = (User) authResult.getPrincipal();
Map<String, Object> headers = new HashMap<>();
headers.put("typ", "JWT");
headers.put("alg", "HS512");
Map<String, Object> payloads = new HashMap<>();
payloads.put("exp", new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME));
payloads.put("username", user.getUsername());
payloads.put("userinfo", user.getInfo());
String token = Jwts.builder()
.setHeader(headers)
.setClaims(payloads)
.signWith(SignatureAlgorithm.HS512, SecurityConstants.TOKEN_SECRET)
.compact();
WebSecurity
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
private final UserService userDetailsService;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
public WebSecurity(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.userDetailsService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.POST, SecurityConstants.SIGN_UP_URL).permitAll()
.anyRequest().authenticated().and()
.addFilter(getAuthenticationFilter());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder);
}
private AuthenticationFilter getAuthenticationFilter() throws Exception {
final AuthenticationFilter filter = new AuthenticationFilter(authenticationManager());
filter.setFilterProcessesUrl(SecurityConstants.SIGN_UP_URL);
return filter;
}
}
SecurityConstants
public class SecurityConstants {
public static final long EXPIRATION_TIME = 10 * 24 * 60 * 60 * 1000;
public static final String TOKEN_PREFIX = "Bearer ";
public static final String HEADER_STRING = "Authorization";
public static final String SIGN_UP_URL = "/users/login";
public static final String TOKEN_SECRET = "kahgskdfksgdsdsf";
}
UserServiceImpl as UserDetailsService
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
UserEntity userEntity = userRepository.findByEmail(email);
if(userEntity == null) {
throw new UsernameNotFoundException(email);
}
return new User(userEntity.getEmail(), userEntity.getEncryptedPassword(), new ArrayList<>());
}
Login Request
curl --location --request POST 'http://localhost:8080/users/login' \
--header 'Content-Type: application/json' \
--header 'Cookie: JSESSIONID=A3C5D7FF91B6562403AB251E2AC52E54' \
--data-raw '{
"email": "[email protected]",
"password": "1234"
}'
Response with UserID
@Component
public class SpringApplicationContext implements ApplicationContextAware {
private static ApplicationContext CONTEXT;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
CONTEXT = applicationContext;
}
public static Object getBean(String beanName) {
return CONTEXT.getBean(beanName);
}
}
UserDto getUser(String email);
@Override
public UserDto getUser(String email) {
UserEntity userEntity = userRepository.findByEmail(email);
if(userEntity == null) {
throw new UsernameNotFoundException(email);
}
UserDto returnValue = new UserDto();
BeanUtils.copyProperties(userEntity, returnValue);
return returnValue;
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException, ServletException {
String username = ((User) authResult.getPrincipal()).getUsername();
String token = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SecurityConstants.TOKEN_SECRET)
.compact();
UserService userService = (UserService)SpringApplicationContext.getBean("userServiceImpl");
UserDto userDto = userService.getUser(username);
response.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
response.addHeader("UserID", userDto.getUserId());
}