发生意外错误(类型为禁止,状态为403)。拒绝访问

时间:2020-07-07 07:58:39

标签: spring-boot microservices spring-cloud

发生意外错误(类型=禁止,状态= 403)。拒绝访问。 当我尝试从邮递员或浏览器访问URL时,出现错误消息“发生意外错误(类型=禁止,状态= 403)”。访问被拒绝。

1)网络安全等级:-

import javax.servlet.Filter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.photoapp.users.service.ApiUserService;

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
     
    private Environment environment;
    private ApiUserService apiUserService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    
    @Autowired
    public WebSecurity(Environment environment , ApiUserService apiUserService , BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.environment = environment;
        this.apiUserService = apiUserService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        http.authorizeRequests().antMatchers("/**").hasIpAddress(environment.getProperty("gateway.ip"))
        .and()
        .addFilter(getAuthenticationFilter());
        http.headers().frameOptions().disable();
    }

    private AuthenticationFilter getAuthenticationFilter() throws Exception {
        // TODO Auto-generated method stub
        AuthenticationFilter authenticationFilter = new AuthenticationFilter();
        authenticationFilter.setAuthenticationManager(authenticationManager());
        return authenticationFilter;
    }
    
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(apiUserService).passwordEncoder(bCryptPasswordEncoder);
    }
}

2)身份验证过滤器类别:-

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.photoapp.users.model.LoginRequestModel;

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    public Authentication attemptAuthentiation(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
        
        try {
            LoginRequestModel creds = new ObjectMapper()
                    .readValue(req.getInputStream() , LoginRequestModel.class);
            
            return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken (
                    creds.getEmail(),
                    creds.getPassword(),
                    new ArrayList<>()));
        }
        catch(IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    protected void succeddfulAuthentication(HttpServletRequest req, HttpServletResponse res , FilterChain chain , Authentication auth) throws IOException , ServletException {
        
    }
}

3)控制器类:-

import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.photoapp.users.dto.UserDto;
import com.photoapp.users.model.CreateUserRequestModel;
import com.photoapp.users.model.CreateUserResponseModel;
import com.photoapp.users.service.ApiUserService;

@RestController
@RequestMapping("/users")
public class UsersController {

    @Autowired
    private ApiUserService apiUserService;
    
    @GetMapping("/status/check")
    public String status() {
        return "Working";
    }

    @PostMapping( consumes = {MediaType.APPLICATION_XML_VALUE , MediaType.APPLICATION_JSON_VALUE } ,
                  produces = {MediaType.APPLICATION_XML_VALUE , MediaType.APPLICATION_JSON_VALUE })
    public ResponseEntity<CreateUserResponseModel> createUser(@RequestBody CreateUserRequestModel userDetails) {
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserDto userDto = modelMapper.map(userDetails, UserDto.class);
        UserDto createdUser = apiUserService.createUser(userDto);
        CreateUserResponseModel responseModel = modelMapper.map(createdUser , CreateUserResponseModel.class);
        return ResponseEntity.status(HttpStatus.CREATED).body(responseModel);
    }
}

4)服务实现类:-

import java.util.ArrayList;
import java.util.UUID;

import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.photoapp.users.dao.UserRepository;
import com.photoapp.users.dto.UserDto;
import com.photoapp.users.entity.UserEntity;

@Service
public class ApiUserServiceImpl implements ApiUserService{

    UserRepository userRepository;
    
    BCryptPasswordEncoder bCryptPasswordEncoder;
    
    @Autowired
    public ApiUserServiceImpl(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.userRepository = userRepository;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }
    
    @Override
    public UserDto createUser(UserDto userDetails) {
        
        userDetails.setUserId(UUID.randomUUID().toString());
        userDetails.setEncryptedPassword(bCryptPasswordEncoder.encode(userDetails.getPassword()));
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        UserEntity userEntity = modelMapper.map(userDetails, UserEntity.class);
        userRepository.save(userEntity);
        return userDetails;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        UserEntity userEntity = userRepository.findByEmail(username);
        
        if(userEntity == null) throw new  UsernameNotFoundException(username);
        return new User(userEntity.getEmail() , userEntity.getEncryptedPassword() , true ,true ,true ,true , new ArrayList<>());
    }
}

2 个答案:

答案 0 :(得分:0)

可以检查环境变量中是否设置了gateway.ip属性吗?如果是Mac,请尝试回显$ {gateway.ip}。

还有一点是为什么您只限制一个IP?有什么具体原因吗? 还可以确认删除.hasIpAddress(environment.getProperty(“ gateway.ip”))是否有效?

答案 1 :(得分:0)

在我的应用程序中,我在Spring Boot安全性配置中配置AuthenticationEntryPoint,因为如果发生任何错误(甚至没有找到我的自定义404-项也未找到),Spring Boot捕获到错误并返回401(对于我而言),但是我记得有人告诉过403.所以我认为403可能会对您隐藏真正的错误

因此,您可以尝试通过配置异常处理来捕获错误

.exceptionHandling()。authenticationEntryPoint(new AppAuthenticationEntryPoint())

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.headers().frameOptions().sameOrigin();
        http.cors();
        http.csrf().disable()
            .authorizeRequests().antMatchers("/", "/callback", "/login**", "/webjars/**", "/error**").permitAll()
            .and()
            .authorizeRequests().antMatchers("/api/**").authenticated()
            .and()
            .authorizeRequests().antMatchers("/h2-console/**").permitAll()
            .and()
            .authorizeRequests().antMatchers("/swagger-ui.html").permitAll()
            .and()
            .authorizeRequests().antMatchers("/swagger-ui/**").permitAll()
            .and()
            .exceptionHandling().authenticationEntryPoint(new AppAuthenticationEntryPoint())
            .and()
            .logout().permitAll().logoutSuccessUrl("/");
    }
    
    @Bean
    public PrincipalExtractor getPrincipalExtractor(){
        return new KeyCloakUserInfoExtractorService();
    }
    
    @Autowired
    private ResourceServerTokenServices resourceServerTokenServices;
}

我的AuthenticationEntryPoint看起来像:

@ControllerAdvice
public class AppAuthenticationEntryPoint implements AuthenticationEntryPoint{

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException auth) throws IOException, ServletException {
        // 401
        setResponseError(response, HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed");
    }
    
    @ExceptionHandler (value = {AccessDeniedException.class})
    public void commence(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
        // 403
        setResponseError(response, HttpServletResponse.SC_FORBIDDEN, String.format("Access Denies: %s", accessDeniedException.getMessage()));
    }
    
    @ExceptionHandler (value = {NotFoundException.class})
    public void commence(HttpServletRequest request, HttpServletResponse response, NotFoundException notFoundException) throws IOException {
        // 404
        setResponseError(response, HttpServletResponse.SC_NOT_FOUND, String.format("Not found: %s", notFoundException.getMessage()));
    }
    
    @ExceptionHandler (value = {Exception.class})
    public void commence(HttpServletRequest request, HttpServletResponse response, Exception exception) throws IOException {
        //logger.error(String.format("An error occurred during request: %s %s error message: %s", 
                     //request.getMethod(), request.getRequestURL(), exception.getMessage()));
        // 500
        setResponseError(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, String.format("Internal Server Error: %s", exception.getMessage()));
    }
    
    private void setResponseError(HttpServletResponse response, int errorCode, String errorMessage) throws IOException{
        response.setStatus(errorCode);
        response.getWriter().write(errorMessage);
        response.getWriter().flush();
        response.getWriter().close();
    }
    
    //private final Logger logger = LoggerFactory.getLogger(this.getClass());
}

希望它可以帮助您了解403的原因