WEB/Security

Lesson 6 - Multiple Authentication Providers Part 1 ,2

Tony Lim 2022. 5. 5. 19:11
728x90
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

 

728x90