# #java #firebase #spring-boot #servlets #firebase-authentication
Вопрос:
Я создал пользовательский фильтр для проверки маркера идентификатора, полученного от Firebase, и как только маркер будет проверен, я выбираю пользователя и устанавливаю объект пользователя для запроса в качестве атрибута. Чтобы я мог получить доступ к этому объекту в своем контроллере. Но цепочка не работает. Это какая-то проблема или анти-шаблон? Есть ли лучший способ сделать это весной?
@Component
@Slf4j
public class JWTRequestFilter extends OncePerRequestFilter {
private static final Logger logger = LoggerFactory.getLogger(JWTRequestFilter.class);
@Autowired
SecurityService securityService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
EnumMap<AuthType, Object> firebaseUser = verifyToken(request);
if(firebaseUser.containsKey(AuthType.PHONE_NUMBER)){
request.setAttribute(AuthType.PHONE_NUMBER.getShortCode(), firebaseUser.get(AuthType.PHONE_NUMBER));
}else if(firebaseUser.containsKey(AuthType.GOOGLE)){
request.setAttribute(AuthType.GOOGLE.getShortCode(), firebaseUser.get(AuthType.GOOGLE));
}else if(firebaseUser.containsKey(AuthType.FACEBOOK)){
request.setAttribute(AuthType.FACEBOOK.getShortCode(), firebaseUser.get(AuthType.FACEBOOK));
}
if(SecurityContextHolder.getContext().getAuthentication() == null){
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
firebaseUser, "");
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
try {
filterChain.doFilter(request, response);
}catch (Exception e){
e.printStackTrace();
}
}
private EnumMap<AuthType, Object> verifyToken(HttpServletRequest request) {
EnumMap<AuthType, Object> firebaseUser = null;
String token = securityService.getBearerToken(request);
try {
if (token != null amp;amp; !token.equalsIgnoreCase("undefined")) {
FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(token);
logger.info("decodedToken claims :: " decodedToken.getClaims());
Map<String, Object> claims = (Map<String, Object>) decodedToken.getClaims();
String signInProvider = (String) ((Map<String, Object>) claims.get("firebase")).get("sign_in_provider");
Credentials.CredentialType type = Credentials.CredentialType.ID_TOKEN;
firebaseUser = generateFirebaseUser(signInProvider, claims);
}
} catch (FirebaseAuthException e) {
e.printStackTrace();
log.error("Firebase Exception:: ", e.getLocalizedMessage());
}
return firebaseUser;
}
private static EnumMap<AuthType, Object> generateFirebaseUser(String provider, Map<String, Object> claims) {
EnumMap<AuthType, Object> firebaseUserMap = new EnumMap<>(AuthType.class);
if (provider.equals("phone")) {
FirebasePhoneUser firebaseUser = new FirebasePhoneUser();
firebaseUser.setAudience((String) claims.get("aud"));
firebaseUser.setAuthTime((Long) claims.get("auth_time"));
firebaseUser.setExpiry((Long) claims.get("exp"));
firebaseUser.setIssuesAtTime((Long) claims.get("iat"));
firebaseUser.setIss((String) claims.get("iss"));
firebaseUser.setSub((String) claims.get("sub"));
firebaseUser.setFirebase((ArrayMap) claims.get("firebase"));
firebaseUser.setUserId((String) claims.get("user_id"));
firebaseUser.setPhoneNumber((String) claims.get("phone_number"));
firebaseUserMap.put(AuthType.PHONE_NUMBER, firebaseUser);
} else if (provider.equals("google.com")) {
logger.info("The claims object has this info :: " claims);
FirebaseGoogleUser firebaseUser = new FirebaseGoogleUser();
firebaseUser.setAudience((String) claims.get("aud"));
firebaseUser.setAuthTime((Long) claims.get("auth_time"));
firebaseUser.setExpiry((Long) claims.get("exp"));
firebaseUser.setIssuesAtTime((Long) claims.get("iat"));
firebaseUser.setIss((String) claims.get("iss"));
firebaseUser.setSub((String) claims.get("sub"));
firebaseUser.setFirebase((ArrayMap) claims.get("firebase"));
firebaseUser.setUserId((String) claims.get("user_id"));
firebaseUser.setEmail((String) claims.get("email"));
firebaseUser.setName((String) claims.get("name"));
firebaseUser.setPicture((String) claims.get("picture"));
firebaseUser.setEmailVerified((Boolean) claims.get("email_verified"));
firebaseUserMap.put(AuthType.GOOGLE, firebaseUser);
} else if (provider.equals("facebook.com")) {
FirebaseFacebookUser firebaseUser = new FirebaseFacebookUser();
firebaseUser.setAudience((String) claims.get("aud"));
firebaseUser.setAuthTime((Long) claims.get("auth_time"));
firebaseUser.setExpiry((Long) claims.get("exp"));
firebaseUser.setIssuesAtTime((Long) claims.get("iat"));
firebaseUser.setIss((String) claims.get("iss"));
firebaseUser.setSub((String) claims.get("sub"));
firebaseUser.setFirebase((ArrayMap) claims.get("firebase"));
firebaseUser.setUserId((String) claims.get("user_id"));
firebaseUser.setName((String) claims.get("name"));
firebaseUser.setPicture((String) claims.get("picture"));
firebaseUserMap.put(AuthType.FACEBOOK, firebaseUser);
}
return firebaseUserMap;
}
}
Вот мой контроллер, в котором я пытаюсь извлечь атрибут из запроса. Это не работает.
@PostMapping(value = "/register")
public ResponseEntity<APIResponse> registerBuyer(@RequestBody RegistrationRequest registrationRequest) {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
LOGGER.info("<-----------------START---------------->");
printHttpServletRequest(request);
LOGGER.info("<-----------------END---------------->");
Enumeration enumeration = request.getAttributeNames();
while(enumeration.hasMoreElements()){
LOGGER.info("<-----------------Enum START---------------->");
String name = (String) enumeration.nextElement();
LOGGER.info(name);
LOGGER.info("<-----------------Enum END---------------->");
}
APIResponse apiResponse = new APIResponse();
return ResponseEntity.ok(apiResponse);
}