像本主题中一样,我在弹簧安全性和角度应用程序方面遇到问题。当我单击身份验证按钮时,即使输入了正确的数据,我也会在控制台中看到:
已从CORS策略阻止对来自源’ http:// localhost:4200 ‘的’ http:// localhost:8080 / api / v1 / basicauth ‘ 处的XMLHttpRequest的访问:对预检请求的响应未通过访问控制检查:它没有HTTP正常状态。
和
GET http:// localhost:8080 / api / v1 / basicauth net :: ERR_FAILED
这是我的角度代码:
验证服务
import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AuthenticationService { // BASE_PATH: 'http://localhost:8080' USER_NAME_SESSION_ATTRIBUTE_NAME = 'authenticatedUser' public username: String; public password: String; constructor(private http: HttpClient) { } authenticationService(username: String, password: String) { return this.http.get(`http://localhost:8080/api/v1/basicauth`, { headers: { authorization: this.createBasicAuthToken(username, password) } }).pipe(map((res) => { this.username = username; this.password = password; this.registerSuccessfulLogin(username, password); })); } createBasicAuthToken(username: String, password: String) { return 'Basic ' + window.btoa(username + ":" + password) } registerSuccessfulLogin(username, password) { sessionStorage.setItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME, username) } logout() { sessionStorage.removeItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME); this.username = null; this.password = null; } isUserLoggedIn() { let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME) if (user === null) return false return true } getLoggedInUserName() { let user = sessionStorage.getItem(this.USER_NAME_SESSION_ATTRIBUTE_NAME) if (user === null) return '' return user } }
login.component.ts
import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { AuthenticationService } from './auth.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html', styleUrls: ['./login.component.css'] }) export class LoginComponent implements OnInit { username: string; password : string; errorMessage = 'Invalid Credentials'; successMessage: string; invalidLogin = false; loginSuccess = false; constructor( private route: ActivatedRoute, private router: Router, private authenticationService: AuthenticationService) { } ngOnInit() { } handleLogin() { this.authenticationService.authenticationService(this.username, this.password).subscribe((result)=> { this.invalidLogin = false; this.loginSuccess = true; this.successMessage = 'Login Successful.'; this.router.navigate(['/products']); }, () => { console.log(this.username); console.log(this.password); this.invalidLogin = true; this.loginSuccess = false; }); } }
http.service.ts
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { AuthenticationService } from './login/auth.service'; @Injectable() export class HttpInterceptorService implements HttpInterceptor { constructor(private authenticationService: AuthenticationService) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { if (this.authenticationService.isUserLoggedIn() && req.url.indexOf('basicauth') === -1) { const authReq = req.clone({ headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Basic ${window.btoa(this.authenticationService.username + ":" + this.authenticationService.password)}` }) }); return next.handle(authReq); } else { return next.handle(req); } } }
login.component.html
<div class="container col-lg-6"> <h1 class="text-center">Login</h1> <div class="card"> <div class="card-body"> <form class="form-group"> <div class="alert alert-warning" *ngIf='invalidLogin'>{{errorMessage}}</div> <div class="alert alert-success" *ngIf='loginSuccess'>{{successMessage}}</div> <div class="form-group"> <label for="email">User Name :</label> <input type="text" class="form-control" id="username" [(ngModel)]="username" placeholder="Enter User Name" name="username"> </div> <div class="form-group"> <label for="pwd">Password:</label> <input type="password" class="form-control" [(ngModel)]="password" id="password" placeholder="Enter password" name="password"> </div> <button (click)=handleLogin() class="btn btn-success">Login</button> </form> </div> </div> </div>
而我在Java中的代码:
package com.shop.shop.security; import org.springframework.http.HttpMethod; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception{ httpSecurity.csrf().disable() .authorizeRequests() .antMatchers(HttpMethod.OPTIONS, "/**") .permitAll() .anyRequest() .authenticated() .and() .httpBasic(); } } package com.shop.shop.security; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @CrossOrigin(origins = "http://localhost:4200") @RestController @RequestMapping("api/v1") public class BasicAuthController { @GetMapping(path = "/basicauth") public AuthenticationBean basicauth(){ return new AuthenticationBean("You are authenticated!"); } } package com.shop.shop.security; public class AuthenticationBean { private String message; public AuthenticationBean(String message) { this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { return String.format("HelloWorldBean [message=%s]", message); } }
您能帮我解决和理解这种问题吗?谢谢!:)
问题与CORS有关,您应该添加以下内容:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; System.out.println("CORSFilter HTTP Request: " + request.getMethod()); // Authorize (allow) all domains to consume the content ((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Origin", "*"); ((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Methods","GET, OPTIONS, HEAD, PUT, POST"); HttpServletResponse resp = (HttpServletResponse) servletResponse; // For HTTP OPTIONS verb/method reply with ACCEPTED status code -- per CORS handshake if (request.getMethod().equals("OPTIONS")) { resp.setStatus(HttpServletResponse.SC_ACCEPTED); return; } // pass the request along the filter chain chain.doFilter(request, servletResponse); }