Angular 带有弹簧安全性(+;角度)的弹簧引导返回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

我的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-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中提供名称。详见文档。请参考这篇文章,它能够用你发布的文件重现这个问题。我也犯了同样的错误