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

Jav*_*Net 5 spring spring-security spring-boot angular

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

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

一旦rest成功,在auth.service.ts的登录方法中设置cookie。

如何对从 Spring Security 返回的 cookie 进行角度设置,请帮助....

这是代码:

登录.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>
Run Code Online (Sandbox Code Playgroud)

登录.component.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";
        }
      )
  }
}
Run Code Online (Sandbox Code Playgroud)

auth.service.ts

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));
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

配置文件

@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();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试控制器.java

public class TestController {

    @CrossOrigin
    @RequestMapping("/testRest")
    public String testRest() {
        Map<String, String> test= new HashMap<>();
        test.put("key", "Test Value");
        return test;
    }
}
Run Code Online (Sandbox Code Playgroud)

pom.xml

<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>
Run Code Online (Sandbox Code Playgroud)

Jav*_*Net 3

{withCredentials: true}还需要在进行登录休息呼叫时进行设置。

而是编写一个 HttpInterceptor。

auth.interceptor.ts

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

并添加到app.module的providers数组中

应用程序模块.ts

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,
    }
]
Run Code Online (Sandbox Code Playgroud)