【发布时间】:2020-10-18 19:55:18
【问题描述】:
我在 Spring Boot 应用程序中添加了 Spring Security,并且无论用户是否登录,我都有一些 API 端点需要调用。(我的意思是这些是我需要在前端检索数据的其余端点角度)。
所以,我将其配置为:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService customUserDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().
disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**")
.permitAll()
.antMatchers("/books").permitAll()
.antMatchers("/api/v1/search/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
}
我所有的 api 都暴露自:http://localhost:8080/api/v1/,比如:
http://localhost:8080/api/v1/books
http://localhost:8080/api/v1/bookcategory
我已经使用.antMatchers("/api/v1/search/**") 进行了配置,我的restendpoint 配置是:
@RequestMapping("/api/v1")
@RestController
@CrossOrigin(origins ="http://localhost:4200")
public class BasicAuthController {
@GetMapping(path = "/basicauth")
public AuthenticationBean basicauth() {
System.out.println("hitted here");
return new AuthenticationBean("You are authenticated");
}
}
我允许 csfr 政策使用:
@Configuration
public class RepositoryConfig implements RepositoryRestConfigurer{
@Autowired
private EntityManager entityManager;
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(entityManager.getMetamodel().getEntities().stream()
.map(Type::getJavaType).toArray(Class[]::new));
//to handle cross origin
config.getCorsRegistry().addMapping("/**").allowedOrigins("http://localhost:4200");
}
}
BookRepository.java
public interface BookRepository extends JpaRepository<Book,Long> {
@RestResource(path = "categoryid")
Page<Book> findByCategoryId(@Param("id") Long id,Pageable pageable);
//to get book by searching
@RestResource(path = "searchbykeyword")
Page<Book> findByNameContaining(@Param("xyz") String keyword,Pageable pageable);
}
正面我有角 9 为:
auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthService {
// 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)
}
}
//我没有粘贴所有代码。
所以,当我转到链接 http://localhost:4200/books 时出现错误:
【问题讨论】:
-
您能否尝试使用邮递员的
localhost:8080/api/...和OPTIONS方法,看看是否返回了Access-Control-Allow-Origin标头,它的值是localhost:4200或*,阅读更多这里developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS -
我在邮递员中试过这个:curl -X OPTIONS localhost:8080/api/v1/books -i 我得到了无法得到任何回应
-
你确定你从角度调用的这个端点是正确的吗?我一直在使用 angular+springboot,我意识到当 angular 找不到目的地时,浏览器会发送一个 CORS 错误
-
是的,当我从 Angular 发送用户名和密码时,登录成功发生,当我在浏览器上点击其余端点时,我看到了数据,但是当这些目标链接被称为 CSRF 策略时api 正在从角度获取
-
如果在使用 OPTIONS 时没有得到响应,这意味着你没有配置你的 API 来捕捉这个方法,你必须添加它
标签: java angular spring spring-boot spring-security