headers定义如下:
@Bean
public HttpHeaders getHttpHeaders(){
HttpHeaders httpHeaders = new HttpHeaders();
String authInfo = "admin:123456";
byte [] encodedAuthInfo = Base64.getEncoder().encode(authInfo.getBytes(Charset.forName("US-ASCII")));
authInfo = "Basic " + new String(encodedAuthInfo);
httpHeaders.set("Authorization" , authInfo);//将授权信息保存到Header中
return httpHeaders;
}
发送POST请求
restTemplate.exchange(ADD_DEPT_URL,HttpMethod.POST,new HttpEntity(dept,this.httpHeaders),Object.class).getBody();
出现:org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 null
发送GET请求可以通过验证
配置文件:
spring:
security:
user:
name: admin #认证用户名
password: 123456 #认证密码
roles: #授权角色
- USER
- ADMIN
之前的SpringBoot1.5.4.RELEASE没有这个问题
试试看。
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(username, password));
restTemplate.getForObject(url, String.class);
说实话,我也不熟悉springsecurity
。
POST 请求还是不能通过验证,但是不用POST Rest服务就无法使用这个注解@RequestBody接收参数了。
是因为 [SpringBoot2.1.5.RELEASE] 有Bug吗
SpringBoot2.1.5.RELEASE 用的是Spring Security5 。
在Spring Security5这个版本认证中需要使用PasswordEncoder,
@Bean//配置了@Bean相当于配置了auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder() ); 或auth.userDetailsService(userServiceDetails).passwordEncoder(new BCryptPasswordEncoder())
//客户端输入的密码会被此加密器加密
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("admin").password(getPasswordEncoder().encode("123456")).roles("USER");//而此处的密码加密相当于给数据库中的已经注册用户密码加密
}
如果服务提供者不配置passwordEncoder,消费者通过RestTemplate访问会导致401错误,而至于GET请求正常,POST请求异常,是因为服务提供者设置了CSRF保护。
但CSRF是一种依赖web浏览器持久化授权(例如cookie或者HTTP授权,也就是基于已登录)的一种攻击,在本处使用RestTemplate自然不在这个范围,另外服务提供者通常设置session无状态,登陆都登陆不了,更谈不上CSRF攻击,所以可以设置关闭保护: .csrf().disable();,然后消费者访问时就没有401错误了!
1 Like