1
1
.
.
1
1
0
0
.
.
4
4
S
S
t
t
e
e
p
p
4
4
:
:
R
R
e
e
s
s
t
t
r
r
i
i
c
c
t
t
A
A
c
c
c
c
e
e
s
s
s
s
I
I
n
n
f
f
o
o
[
[
G
G
]
]
In this tutorial we will show how to restrict access to Endpoints based on 2FA Authentication.
In other words to check if User has passed 2FA Authentication before allowing him to access certain Endpoints.
More specifically, if google2faRrequiered = true then it must also be google2faAuthenticated = true (valid Code entered).
Endpoints to /Configure, /EnterCode and /VerifyCode will be restricted behind standard Username and Password.
But they will be accessible if User is not 2FA Authenticated (since they are needed to perform 2FA Authentication).
Endpoint /Hello will be restricted behind 2FA Authenticated.
Use will be able to access it only when google2faRrequiered = true and google2faAuthenticated = true (valid Code).
Application Schema [Results]
SecurityConfig
AccountService
AccountLoader
AccountRepository
http://localhost:8080/Configure
Tomcat
configure()
Browser
Account
SecurityBeans
Google2faFilter
Configure.html
EnterCode.html
MyController
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Class: Google2faFilter.java (inside package config)
Google2faFilter.java
package com.ivoronline.springboot_security_2fa.config;
import com.ivoronline.springboot_security_2fa.entities.Account;
import com.ivoronline.springboot_security_2fa.repositories.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class Google2faFilter extends GenericFilterBean {
@Autowired
private AccountRepository accountRepository;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain
filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//ALLOW ACCESS TO FOLLOWING URLS
RequestMatcher urlConfigure = new AntPathRequestMatcher("/Configure");
RequestMatcher urlEnterCode = new AntPathRequestMatcher("/EnterCode");
RequestMatcher urlVerifyCode = new AntPathRequestMatcher("/VerifyCode");
if (urlConfigure.matches(request) || urlEnterCode.matches(request) || urlVerifyCode.matches(request)) {
filterChain.doFilter(request, response);
return;
}
//GET ACCOUNT
User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = user.getUsername();
Account account = accountRepository.findByUsername(username);
//CHECK IF ACCOUNT SHOULD BE 2FA AUTHENTICATED
if (account.google2faEnabled && !account.google2faAuthenticated) {
System.out.println("Account is not 2FA Authenticated");
return;
}
//ALLOW ACCESS IF ACCOUNT SHOULD NOT BE 2FA AUTHENTICATED
filterChain.doFilter(request, response);
return;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Configure
You get redirected to http://localhost:8080/login
– Username: john
– Password: johnpassword
– Sign in
You get redirected back to http://localhost:8080/Configure (shows QRCode)
– Scan QRCode with Google Authenticator (Mobile Phone App)
– It should show a Temporary Code: 267 189
– Enter Temporary Code
You get redirected to http://localhost:8080/EnterCode
– Enter Temporary Code: 267 189
– Submit
You get redirected to http://localhost:8080/VerifyCode (account.google2faAuthenticated = true)
Test Access
– http://localhost:8080/Hello (allowed access google2faAuthenticated = true)
– Set account.google2faAuthenticated = false
– http://localhost:8080/Hello (restricted access google2faAuthenticated = false)
– http://localhost:8080/EnterCode
– Enter Temporary Code: 332815
– Submit
– http://localhost:8080/Hello (allowed access google2faAuthenticated = true)
http://localhost:8080/login - john - johnpassword http://localhost:8080/Configure
Scanning with Google Authenticator Mobile App http://localhost:8080/EnterCode
http://localhost:8080/VerifyCode?code=267189 http://localhost:8080/Hello (Can access)
Account
http://localhost:8080/Hello (allowed access for true) http://localhost:8080/Hello (restricted access for false)
http://localhost:8080/EnterCode http://localhost:8080/VerifyCode
http://localhost:8080/Hello (allowed access for true)