Angular5-从spring表单登录返回的设置cookie

Angular5-从spring表单登录返回的设置cookie,spring,angular,spring-boot,spring-security,Spring,Angular,Spring Boot,Spring Security,我正在尝试将spring安全性添加到使用angular5和spring boot 1.5.8构建的应用程序中。我试图添加的身份验证机制是SpringBoot的formLogin 我通过rest调用验证用户,而不是通过默认的表单操作。登录正常,但随后的rest调用失败。我正在使用cookies“打开”进行rest调用,以便它将cookies发送到spring应用程序,但请求仍然失败。原因是angular没有设置从身份验证返回的响应cookies rest成功后,在auth.service.ts的登

我正在尝试将spring安全性添加到使用angular5和spring boot 1.5.8构建的应用程序中。我试图添加的身份验证机制是SpringBoot的formLogin

我通过rest调用验证用户,而不是通过默认的表单操作。登录正常,但随后的rest调用失败。我正在使用cookies“打开”进行rest调用,以便它将cookies发送到spring应用程序,但请求仍然失败。原因是angular没有设置从身份验证返回的响应cookies

rest成功后,在auth.service.ts的登录方法中设置Cookie

如何设置从spring security返回的Cookie请帮助

代码如下:

login.component.html

<form name="form-signin" (ngSubmit)="login()" #f="ngForm" novalidate>
  <div class="form-group" >
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" [(ngModel)]="user.username" />
  </div>
  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" class="form-control" id="password" name="password" [(ngModel)]="user.password" />        
  </div>
  </div>
  <button class="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button>
</form>
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> 
    </parent>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.196</version>
        </dependency>
</dependencies>
auth.service.ts

export class LoginComponent implements OnInit {
  user: User=new User();
  constructor(private authService :AuthService, private router: Router) { }

  ngOnInit() {
  }

  login(){
    this.authService.logIn(this.user).subscribe(data=>{
            this.authService.testRest().subscribe(data=>{
            this.router.navigate(['/dashboard']);
            });
        },err=>{
            this.errorMessage="error :  Username or password is incorrect";
        }
      )
  }
}
export class AuthService {
  constructor(public http: HttpClient) { }

  public logIn(user: User){
    const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type':  'application/x-www-form-urlencoded'
    })
    };
    let body = new URLSearchParams();
    body.set('username', user.username);
    body.set('password', user.password);

    return this.http.post(AppComponent.API_URL+"/login" , body.toString() ,  httpOptions)
      .map((response: Response) => {
     //How to make angular set cookies here
      console.log(JSON.stringify(response));
    });
  }

  testRest() {
    return this.http.get(AppComponent.API_URL+"/testRest", { withCredentials: true }) .map((response: Response) => {
      console.log(JSON.stringify(response));
    });
  }
}
import { Observable } from 'rxjs/Observable';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      withCredentials: true
  });
  return next.handle(request);
  }
}
import { AuthInterceptor } from './services/auth.interceptor';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
imports: [
    BrowserModule,HttpClientModule,FormsModule
  ],

providers: [
    {
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
    }
]
WebConfig.java

@Configurable
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AppUserDetailsService appUserDetailsService;
    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .roles("USER");
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:4200");

            }
        };
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        .authorizeRequests()
        .antMatchers("/login")
        .permitAll()
        .anyRequest()
        .fullyAuthenticated()
        .and()
        .logout()
        .permitAll()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST"))
        .and()
       .formLogin().successHandler(customAuthenticationSuccessHandler).failureHandler(customAuthenticationFailureHandler)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        .and()
        .csrf()
        .disable();
    }
}
public class TestController {

    @CrossOrigin
    @RequestMapping("/testRest")
    public String testRest() {
        Map<String, String> test= new HashMap<>();
        test.put("key", "Test Value");
        return test;
    }
}
TestController.java

@Configurable
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AppUserDetailsService appUserDetailsService;
    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("password")
                .roles("USER");
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:4200");

            }
        };
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        .authorizeRequests()
        .antMatchers("/login")
        .permitAll()
        .anyRequest()
        .fullyAuthenticated()
        .and()
        .logout()
        .permitAll()
        .logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST"))
        .and()
       .formLogin().successHandler(customAuthenticationSuccessHandler).failureHandler(customAuthenticationFailureHandler)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
        .and()
        .csrf()
        .disable();
    }
}
public class TestController {

    @CrossOrigin
    @RequestMapping("/testRest")
    public String testRest() {
        Map<String, String> test= new HashMap<>();
        test.put("key", "Test Value");
        return test;
    }
}
公共类TestController{
@交叉起源
@请求映射(“/testRest”)
公共字符串testRest(){
Map test=newhashmap();
测试。输入(“键”、“测试值”);
回归试验;
}
}
pom.xml

<form name="form-signin" (ngSubmit)="login()" #f="ngForm" novalidate>
  <div class="form-group" >
    <label for="username">Username</label>
    <input type="text" class="form-control" id="username" name="username" [(ngModel)]="user.username" />
  </div>
  <div class="form-group">
    <label for="password">Password</label>
    <input type="password" class="form-control" id="password" name="password" [(ngModel)]="user.password" />        
  </div>
  </div>
  <button class="btn btn-lg btn-primary btn-block btn-signin" type="submit">Sign in</button>
</form>
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> 
    </parent>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.196</version>
        </dependency>
</dependencies>

org.springframework.boot
spring启动程序父级
1.5.8.1发布
org.springframework.boot
spring引导启动器数据jpa
org.springframework.boot
弹簧启动安全
org.springframework.boot
SpringBootStarterWeb
org.springframework.session
春季会议
org.springframework.boot
弹簧靴开发工具
运行时
com.h2数据库
氢
1.4.196

在进行登录rest调用时,需要设置
{withCredentials:true}

而是编写一个HttpInterceptor

auth.interceptor.ts

export class LoginComponent implements OnInit {
  user: User=new User();
  constructor(private authService :AuthService, private router: Router) { }

  ngOnInit() {
  }

  login(){
    this.authService.logIn(this.user).subscribe(data=>{
            this.authService.testRest().subscribe(data=>{
            this.router.navigate(['/dashboard']);
            });
        },err=>{
            this.errorMessage="error :  Username or password is incorrect";
        }
      )
  }
}
export class AuthService {
  constructor(public http: HttpClient) { }

  public logIn(user: User){
    const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type':  'application/x-www-form-urlencoded'
    })
    };
    let body = new URLSearchParams();
    body.set('username', user.username);
    body.set('password', user.password);

    return this.http.post(AppComponent.API_URL+"/login" , body.toString() ,  httpOptions)
      .map((response: Response) => {
     //How to make angular set cookies here
      console.log(JSON.stringify(response));
    });
  }

  testRest() {
    return this.http.get(AppComponent.API_URL+"/testRest", { withCredentials: true }) .map((response: Response) => {
      console.log(JSON.stringify(response));
    });
  }
}
import { Observable } from 'rxjs/Observable';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor() {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    request = request.clone({
      withCredentials: true
  });
  return next.handle(request);
  }
}
import { AuthInterceptor } from './services/auth.interceptor';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http';
imports: [
    BrowserModule,HttpClientModule,FormsModule
  ],

providers: [
    {
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
    }
]