package com.laurentiuspilca.ssc6.security.filters;
import com.laurentiuspilca.ssc6.entities.Otp;
import com.laurentiuspilca.ssc6.repositories.OtpRepository;
import com.laurentiuspilca.ssc6.security.authentications.OtpAuthentication;
import com.laurentiuspilca.ssc6.security.authentications.UsernamePasswordAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
@Component
public class UsernamePasswordAuthFilter
extends OncePerRequestFilter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private OtpRepository otpRepository;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
// Step 1: username & password
// Step 2: username & otp
var username = request.getHeader("username");
var password = request.getHeader("password");
var otp = request.getHeader("otp");
if (otp == null) {
// step 1
Authentication a = new UsernamePasswordAuthentication(username, password);
a = authenticationManager.authenticate(a);
// we generate an OTP
String code = String.valueOf(new Random().nextInt(9999) + 1000);
Otp otpEntity = new Otp();
otpEntity.setUsername(username);
otpEntity.setOtp(code);
otpRepository.save(otpEntity);
} else {
// step 2
Authentication a = new OtpAuthentication(username, otp);
a = authenticationManager.authenticate(a);
// we issue a token
response.setHeader("Authorization", UUID.randomUUID().toString());
}
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
return !request.getServletPath().equals("/login");
}
}
shouldNotFilter will filter "/login" request
but commenting out that method still works -> /login request still pass this filter
but we are not saving otp in disk so we cannot compare when user come with given Authorization="randomUUID"
take away -> by providing 2 Authentication Provider we can AuthenticationManager get to choose right one in our customfilter
notice this token filter doesn't get applied with "/login/ request but all the other request will get filtered by this
when login with token we add token to memory(tokenManager is just Set)
in Authentication filter TokenAuthentication will be authenticated by comparing if give token exisit in memory
here TokenAuthentication is same as UsernamePasswordAuthenticationToken but in reality we need to implement Authentication Inteface and create our own
'WEB > Security' 카테고리의 다른 글
Lesson 9 - (Cross-Site Request Forgery) CSRF (0) | 2022.05.06 |
---|---|
Lesson 8 - The Security Context (0) | 2022.05.06 |
Lesson 5 - The filter chain (0) | 2022.05.05 |
Lesson 4 - The AuthenticationProvider (0) | 2022.05.05 |
Lesson 3 - UserDetailsManager and PasswordEncoder (0) | 2022.05.05 |