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)
{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)