带有Angular + Springboot的Whitelabel错误页面

时间:2020-06-03 22:09:12

标签: angular spring spring-boot spring-security

每当我尝试通过将URL放在浏览器上并按Enter或刷新页面来尝试在Angular 9应用程序中(除根路由之外)加载任何页面时,都会收到Whitelabel错误页面(错误404)。使用页面按钮(角度路由器)加载这些页面效果很好。

我尝试了stackoverflow的许多解决方案来解决此问题,但没有一个奏效。

whitelabel error page

后端主类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GroupsApplication {

    public static void main(String[] args) {
        SpringApplication.run(WarcraftgroupsApplication.class, args);
    }

}

后端SecutiryConfigurer

import com.sampaiodias.groups.auth.filters.JwtRequestFilter;
import com.sampaiodias.groups.auth.services.MyUserDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
public class SecurityConfigurer extends WebSecurityConfigurerAdapter {

    private final MyUserDetailsService myUserDetailsService;
    private final JwtRequestFilter jwtRequestFilter;

    public SecurityConfigurer(MyUserDetailsService myUserDetailsService, JwtRequestFilter jwtRequestFilter) {
        this.myUserDetailsService = myUserDetailsService;
        this.jwtRequestFilter = jwtRequestFilter;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests().antMatchers("/auth", "/user", "/refresh", "/end-session").permitAll()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

前端AppRoutingModule

import { GroupsComponent } from './groups/groups/groups.component';
import { RegisterComponent } from './auth/register/register.component';
import { LoginComponent } from './auth/login/login.component';
import { AppComponent } from './app.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    component: AppComponent,
  },
  {
    path: 'login',
    component: LoginComponent,
  },
  {
    path: 'register',
    component: RegisterComponent,
  },
  {
    path: 'groups',
    component: GroupsComponent,
  },
  { path: '**', redirectTo: '/' },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

前端代理

const PROXY_CONFIG = [
  {
    context: ["/", "/user", "/group", "/character"],
    target: "http://localhost:8080",
    secure: false,
  },
];

module.exports = PROXY_CONFIG;

1 个答案:

答案 0 :(得分:0)

对于在路由模块中设置的每个单个Angular路由,不仅是根路由,必须转发到index.html。有关定义单个控制器以将所有请求转发到index.html的信息,请参见Spring Boot with redirecting with single page angular2

否则,Spring会尝试自行处理url,但是由于它没有针对您输入的URL的@Controller请求映射(因为您希望Angular对其进行处理),因此它将返回404。

编辑

OP是指ng serve,而不是部署的环境。在这种情况下,您必须创建一个ErrorController重定向到ng开发服务器-http://localhost:4200

@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class AngularRedirectErrorController extends AbstractErrorController {

  private final ErrorAttributes errorAttributes;

  public AngularRedirectErrorController(ErrorAttributes errorAttributes) {
    super(errorAttributes);
    this.errorAttributes = errorAttributes;
  }

  @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
  public String redirectToAngular(ServletWebRequest request) {
    Map<String, Object> errorAttrs = errorAttributes.getErrorAttributes(request, false);
    String path = (String) errorAttrs.get("path");
    return "redirect:http://localhost:4200" + path;
  }

  @RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE)
  @ResponseBody
  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    HttpStatus status = getStatus(request);
    if (status == HttpStatus.NO_CONTENT) {
        return new ResponseEntity<>(status);
    }

    WebRequest webRequest = new ServletWebRequest(request);
    Map<String, Object> body = errorAttributes.getErrorAttributes(webRequest, false);
    return new ResponseEntity<>(body, status);
  }

  @Override
  public String getErrorPath() {
    return null;
  }

}