Estou fazendo um modelo de estudo para autorizar o acesso do usuário conforme o seu perfil de acesso. Ex: Tenho um usuário que tem um perfil apenas de leitura, então ele não pode acessar os métodos de uma determinada controller. A lógica de como fazer isso já esta pronto, com as informações no banco de dados. Gostaria de saber se na classe de Filter tenho como lançar uma exceção tratada ou apenas mudar o código de retorno (http) e/ou mensagem do response. Pois quando o token é invalido ou o usuário não tem permissão de acesso, eu apenas não forço a autenticação e o retorno é sempre o mesmo HTTP 403
package com.iberdrola.api.config.security;
import java.io.IOException;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import com.iberdrola.business.domain.User;
import com.iberdrola.business.mapper.UserMapper;
import com.iberdrola.business.service.TokenService;
public class TokenFilterAuthentication extends OncePerRequestFilter{
@Autowired
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
private TokenService tokenService;
private UserMapper userMapper;
public TokenFilterAuthentication(TokenService tokenService, UserMapper userMapper) {
this.tokenService = tokenService;
this.userMapper = userMapper;
}
/**
* Perform token authentication
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String token = retrieveToken(request);
boolean validate = tokenService.isValidToken(token);
if(validate) {
try {
authenticateUser(token, request);
} catch (Exception e) {
response.getWriter().write("Usuário não possui acesso");
response.setStatus(HttpStatus.FORBIDDEN.value());
}
}else {
filterChain.doFilter(request, response);
}
}
/**
* Performs user authentication
* @param token
* @throws Exception
*/
private void authenticateUser(String token, HttpServletRequest request) throws Exception {
Integer idUser = tokenService.getIdUser(token);
User user = userMapper.getUserId(idUser);
boolean validateAcessPermision = accessPermission(user, request);
if(validateAcessPermision) {
UserDetailsDTO userDetails = new UserDetailsDTO(user);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
/**
* Validate access permission
* @param user
* @param request
* @return
* @throws Exception
*/
private boolean accessPermission(User user, HttpServletRequest request) throws Exception {
String[] paths = request.getServletPath().split("/");
List<User> accessPermissionModules = userMapper.getAccessPermissionModulesUser(paths[1], request.getMethod(), user.getProfile().getId(), user.getId());
if(accessPermissionModules != null && !accessPermissionModules.isEmpty()) {
return true;
}
List<User> accessPermissionFeatures = userMapper.getAccessPermissionFeaturesUser(paths[1], request.getMethod(), user.getProfile().getId(), user.getId());
if(accessPermissionFeatures != null && !accessPermissionFeatures.isEmpty()) {
return true;
}
throw new RuntimeException(); // Exception lançada para tentar mudar retorno
}
/**
* Retrieve the user's token
* @param request
* @return
*/
private String retrieveToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if(token == null || token.isEmpty() || !token.startsWith("Bearer ")) {
return null;
}
return token.substring(7, token.length());
}
}