我正在关注this教程,唯一的区别就是我使用Fetch API来查询REST存储库。我的问题是,成功授权后,每个fetch()
调用都会返回包含登录表单html字符串的响应。具体来说,这种代码
fetch(`${root}/employees?size=${pageSize}`).then( p => p.json()})
在Chrome控制台中产生以下错误:
localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token < in
JSON at position 0
如果我添加一个带有fetch
授权的标头:
fetch(`${root}/employees?size=${pageSize}`, {
method: 'GET',
headers: new Headers({'Content-Type': 'application/json',
'Authorization': 'Basic '+btoa('greg:turnquist'))})
一切正常,但在配置Spring Security
beans
之后,这看起来很愚蠢,并且肯定不是最佳做法。
所有java源代码都与教程中的相同,但我在此处包含来自配置类的片段:
SecurityConfiguration.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private SpringDataJpaUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(Manager.PASSWORD_ENCODER);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/build/**", "/main.css").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable()
.logout()
.logoutSuccessUrl("/");
}
}
SpringDataJpaUserDetailsService.java
@Component
public class SpringDataJpaUserDetailsService implements UserDetailsService {
private final ManagerRepository repository;
@Autowired
public SpringDataJpaUserDetailsService(ManagerRepository repository) {
this.repository = repository;
}
@Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Manager manager = this.repository.findByName(name);
return new User(manager.getName(), manager.getPassword(),
AuthorityUtils.createAuthorityList(manager.getRoles()));
}
}
EmployeeRepository.java
@PreAuthorize("hasRole('ROLE_MANAGER')")
public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {
@Override
@PreAuthorize("#employee?.manager == null or #employee?.manager?.name == authentication?.name")
Employee save(@Param("employee") Employee employee);
@Override
@PreAuthorize("@employeeRepository.findOne(#id)?.manager?.name == authentication?.name")
void delete(@Param("id") Long id);
@Override
@PreAuthorize("#employee?.manager?.name == authentication?.name")
void delete(@Param("employee") Employee employee);
}
所以我的问题是如何使用新的javascript
fetch API从授权页面发送凭据,以便与REST存储库进行交互而无需额外的安全配置?
答案 0 :(得分:0)
问题的根源是fetch()
默认情况下不发送Cookie。所以我应该添加credentials: 'include'
来请求选项对象:
fetch(`${root}/employees?size=${pageSize}`, {
method: 'GET',
credentials: 'include'})