【发布时间】:2016-09-24 22:29:59
【问题描述】:
我正在关注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 存储库交互而无需额外的安全配置?
【问题讨论】:
标签: java ajax spring spring-boot