Angular 带有弹簧安全性(+;角度)的弹簧引导返回401错误
我的Spring boot(Spring Security)应用程序在尝试使用登录时返回401错误 我似乎不明白为什么会出现401错误。在我在网上看到的一些例子中,类似的配置似乎起到了作用 以下是请求结果:Angular 带有弹簧安全性(+;角度)的弹簧引导返回401错误,angular,spring,spring-boot,spring-security,basic-authentication,Angular,Spring,Spring Boot,Spring Security,Basic Authentication,我的Spring boot(Spring Security)应用程序在尝试使用登录时返回401错误 我似乎不明白为什么会出现401错误。在我在网上看到的一些例子中,类似的配置似乎起到了作用 以下是请求结果: Request URL: http://localhost:8080/account/login Request Method: GET Status Code: 401 Remote Address: [::1]:8080 Referrer Policy: no-referrer-whe
Request URL: http://localhost:8080/account/login
Request Method: GET
Status Code: 401
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Wed, 24 Apr 2019 08:05:37 GMT
Expires: 0
Pragma: no-cache
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
WWW-Authenticate: Basic realm="Realm", Basic realm="Realm"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Provisional headers are shown
Accept: application/json
Authorization: Basic Y2pAaG90bWFpbC5jb206Y2hyaXMx
Origin: http://localhost:4200
Referer: http://localhost:4200/login
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
package com.neha.jobportal.jobportalbackend.configurations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
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.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.neha.jobportal.jobportalbackend.services.AppUserDetailsService;
@Configurable
@EnableWebSecurity(debug = true)
// Modifying or overriding the default spring boot security.
public class WebConfig extends WebSecurityConfigurerAdapter {
@Autowired
AppUserDetailsService appUserDetailsService;
// This method is for overriding the default AuthenticationManagerBuilder.
// We can specify how the user details are kept in the application. It may
// be in a database, LDAP or in memory.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(appUserDetailsService);
}
// this configuration allow the client app to access the this api
// all the domain that consume this api must be included in the allowed o'rings
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
};
}
// This method is for overriding some configuration of the WebSecurity
// If you want to ignore some request or request patterns then you can
// specify that inside this method
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
/*
* web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui",
* "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
* "/webjars/**", "/swagger-resources/configuration/ui",
* "/swagger-resources/configuration/security");
*/
}
// This method is used for override HttpSecurity of the web Application.
// We can specify our authorization criteria inside this method.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
// starts authorizing configurations
.authorizeRequests()
// ignoring the guest's urls "
.antMatchers("/account/register", "/account/login", "/logout", "/v2/api-docs", "/v2/api-docs",
"/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
"/webjars/**", "/swagger-resources/configuration/ui",
"/swagger-resources/configuration/security", "/swagger-ui.html#/**",
"/swagger-ui.html#/job-portal-controller/**")
.permitAll()
// authenticate all remaining URLS
.anyRequest().fullyAuthenticated().and()
/*
* "/logout" will log the user out by invalidating the HTTP Session, cleaning up
* any {link rememberMe()} authentication that was configured,
*/
.logout().permitAll().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST")).and()
// enabling the basic authentication
.httpBasic().and()
// configuring the session on the server
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
// disabling the CSRF - Cross Site Request Forgery
.csrf().disable();
}
}
package com.neha.jobportal.jobportalbackend.controllers;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.neha.jobportal.jobportalbackend.entities.User;
import com.neha.jobportal.jobportalbackend.services.UserService;
import com.neha.jobportal.jobportalbackend.utils.CustomErrorType;
@RestController
@CrossOrigin
@RequestMapping("account")
public class AccountController {
@Autowired
private UserService userService;
// request method to create a new account by Job Seeker
@CrossOrigin
@PostMapping(value = "/register")
public ResponseEntity<?> createUser(@RequestBody User newUser) {
System.out.println("/register called with " + newUser.toString());
// check email to only allow unregistered emails
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Job Seeker");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// request method to create a new account by a Recruiter
@CrossOrigin
@PostMapping(value = "/registerAsRecruiter")
public ResponseEntity<?> createRecruiter(@RequestBody User newUser) {
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Recruiter");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// this is the login api/service
@CrossOrigin
@RequestMapping("/login")
public Principal user(Principal principal) {
System.out.println("user logged "+principal);
return principal;
}
}
在春天,WebConfig.java看起来像:
Request URL: http://localhost:8080/account/login
Request Method: GET
Status Code: 401
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Wed, 24 Apr 2019 08:05:37 GMT
Expires: 0
Pragma: no-cache
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
WWW-Authenticate: Basic realm="Realm", Basic realm="Realm"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Provisional headers are shown
Accept: application/json
Authorization: Basic Y2pAaG90bWFpbC5jb206Y2hyaXMx
Origin: http://localhost:4200
Referer: http://localhost:4200/login
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
package com.neha.jobportal.jobportalbackend.configurations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
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.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.neha.jobportal.jobportalbackend.services.AppUserDetailsService;
@Configurable
@EnableWebSecurity(debug = true)
// Modifying or overriding the default spring boot security.
public class WebConfig extends WebSecurityConfigurerAdapter {
@Autowired
AppUserDetailsService appUserDetailsService;
// This method is for overriding the default AuthenticationManagerBuilder.
// We can specify how the user details are kept in the application. It may
// be in a database, LDAP or in memory.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(appUserDetailsService);
}
// this configuration allow the client app to access the this api
// all the domain that consume this api must be included in the allowed o'rings
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
};
}
// This method is for overriding some configuration of the WebSecurity
// If you want to ignore some request or request patterns then you can
// specify that inside this method
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
/*
* web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui",
* "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
* "/webjars/**", "/swagger-resources/configuration/ui",
* "/swagger-resources/configuration/security");
*/
}
// This method is used for override HttpSecurity of the web Application.
// We can specify our authorization criteria inside this method.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
// starts authorizing configurations
.authorizeRequests()
// ignoring the guest's urls "
.antMatchers("/account/register", "/account/login", "/logout", "/v2/api-docs", "/v2/api-docs",
"/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
"/webjars/**", "/swagger-resources/configuration/ui",
"/swagger-resources/configuration/security", "/swagger-ui.html#/**",
"/swagger-ui.html#/job-portal-controller/**")
.permitAll()
// authenticate all remaining URLS
.anyRequest().fullyAuthenticated().and()
/*
* "/logout" will log the user out by invalidating the HTTP Session, cleaning up
* any {link rememberMe()} authentication that was configured,
*/
.logout().permitAll().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST")).and()
// enabling the basic authentication
.httpBasic().and()
// configuring the session on the server
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
// disabling the CSRF - Cross Site Request Forgery
.csrf().disable();
}
}
package com.neha.jobportal.jobportalbackend.controllers;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.neha.jobportal.jobportalbackend.entities.User;
import com.neha.jobportal.jobportalbackend.services.UserService;
import com.neha.jobportal.jobportalbackend.utils.CustomErrorType;
@RestController
@CrossOrigin
@RequestMapping("account")
public class AccountController {
@Autowired
private UserService userService;
// request method to create a new account by Job Seeker
@CrossOrigin
@PostMapping(value = "/register")
public ResponseEntity<?> createUser(@RequestBody User newUser) {
System.out.println("/register called with " + newUser.toString());
// check email to only allow unregistered emails
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Job Seeker");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// request method to create a new account by a Recruiter
@CrossOrigin
@PostMapping(value = "/registerAsRecruiter")
public ResponseEntity<?> createRecruiter(@RequestBody User newUser) {
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Recruiter");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// this is the login api/service
@CrossOrigin
@RequestMapping("/login")
public Principal user(Principal principal) {
System.out.println("user logged "+principal);
return principal;
}
}
我的Spring AccountController.java如下所示:
Request URL: http://localhost:8080/account/login
Request Method: GET
Status Code: 401
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Origin: http://localhost:4200
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Wed, 24 Apr 2019 08:05:37 GMT
Expires: 0
Pragma: no-cache
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
WWW-Authenticate: Basic realm="Realm", Basic realm="Realm"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Provisional headers are shown
Accept: application/json
Authorization: Basic Y2pAaG90bWFpbC5jb206Y2hyaXMx
Origin: http://localhost:4200
Referer: http://localhost:4200/login
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
package com.neha.jobportal.jobportalbackend.configurations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
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.builders.WebSecurity;
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.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.neha.jobportal.jobportalbackend.services.AppUserDetailsService;
@Configurable
@EnableWebSecurity(debug = true)
// Modifying or overriding the default spring boot security.
public class WebConfig extends WebSecurityConfigurerAdapter {
@Autowired
AppUserDetailsService appUserDetailsService;
// This method is for overriding the default AuthenticationManagerBuilder.
// We can specify how the user details are kept in the application. It may
// be in a database, LDAP or in memory.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(appUserDetailsService);
}
// this configuration allow the client app to access the this api
// all the domain that consume this api must be included in the allowed o'rings
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
};
}
// This method is for overriding some configuration of the WebSecurity
// If you want to ignore some request or request patterns then you can
// specify that inside this method
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
/*
* web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui",
* "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
* "/webjars/**", "/swagger-resources/configuration/ui",
* "/swagger-resources/configuration/security");
*/
}
// This method is used for override HttpSecurity of the web Application.
// We can specify our authorization criteria inside this method.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
// starts authorizing configurations
.authorizeRequests()
// ignoring the guest's urls "
.antMatchers("/account/register", "/account/login", "/logout", "/v2/api-docs", "/v2/api-docs",
"/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html/**",
"/webjars/**", "/swagger-resources/configuration/ui",
"/swagger-resources/configuration/security", "/swagger-ui.html#/**",
"/swagger-ui.html#/job-portal-controller/**")
.permitAll()
// authenticate all remaining URLS
.anyRequest().fullyAuthenticated().and()
/*
* "/logout" will log the user out by invalidating the HTTP Session, cleaning up
* any {link rememberMe()} authentication that was configured,
*/
.logout().permitAll().logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST")).and()
// enabling the basic authentication
.httpBasic().and()
// configuring the session on the server
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
// disabling the CSRF - Cross Site Request Forgery
.csrf().disable();
}
}
package com.neha.jobportal.jobportalbackend.controllers;
import java.security.Principal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
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.neha.jobportal.jobportalbackend.entities.User;
import com.neha.jobportal.jobportalbackend.services.UserService;
import com.neha.jobportal.jobportalbackend.utils.CustomErrorType;
@RestController
@CrossOrigin
@RequestMapping("account")
public class AccountController {
@Autowired
private UserService userService;
// request method to create a new account by Job Seeker
@CrossOrigin
@PostMapping(value = "/register")
public ResponseEntity<?> createUser(@RequestBody User newUser) {
System.out.println("/register called with " + newUser.toString());
// check email to only allow unregistered emails
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Job Seeker");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// request method to create a new account by a Recruiter
@CrossOrigin
@PostMapping(value = "/registerAsRecruiter")
public ResponseEntity<?> createRecruiter(@RequestBody User newUser) {
if (userService.findUserByUsername(newUser.getUsername()) != null) {
System.out.println("username already exists " + newUser.getUsername());
return new ResponseEntity(
new CustomErrorType("User with username " + newUser.getUsername() + "already exists "),
HttpStatus.CONFLICT);
}
newUser.setRole("Recruiter");
return new ResponseEntity<User>(userService.save(newUser), HttpStatus.CREATED);
}
// this is the login api/service
@CrossOrigin
@RequestMapping("/login")
public Principal user(Principal principal) {
System.out.println("user logged "+principal);
return principal;
}
}
和一个用于Swagger的SwaggerConfig.java
package com.neha.jobportal.jobportalbackend.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig{
@Bean
public Docket produceApi(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.neha.jobportal.jobportalbackend.controllers"))
.build();
}
// Describe your apis
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Job Portal Rest APIs")
.description("This page lists all the rest apis exposed by the Job Portal Backend.")
.version("1.0-SNAPSHOT")
.build();
}
}
尝试将MyCORSFilter重命名为CorsFilter或在@Configuration中提供名称。详见文档。请参考这篇文章,它能够用你发布的文件重现这个问题。我也犯了同样的错误