报错:
"timestamp": "2022-04-28T03:00:27.785+0000",
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"path": "/oauth/token"
}
以下1-8节的方法都可以试试,我试了好多种,只有最后一种成功了
1.postMan请求
1.1表单(请求返回401)
1.2JSON(请求返回401)
1.3加basic认证(请求返回401)
格式:basic空格clientId:clientSecret(base64编码)
2.restTemplate.postForEntity(请求返回401)
Map<String,Object> params = new HashMap<>();
params.put("grant_type", "password");
params.put("scope", "server");
params.put("client_id", clientId);
params.put("client_secret", secret);
params.put("username", username.trim());
params.put("password", password);
ResponseEntity<OAuth2AccessToken> oAuth2AccessTokenResponseEntity = restTemplate.postForEntity("http://localhost:8083/user-service/oauth/token",params,OAuth2AccessToken.class);
if(oAuth2AccessTokenResponseEntity != null) {
// 1、获取token
OAuth2AccessToken oAuth2AccessToken = oAuth2AccessTokenResponseEntity.getBody();
String accessToken = oAuth2AccessToken.getValue();
return accessToken;
}
3.restTemplate.postForObject(请求返回401)
Map<String,Object> params = new HashMap<>();
params.put("grant_type", "password");
params.put("scope", "server");
params.put("client_id", "abc");
params.put("client_secret", "abc");
params.put("username", "test");
params.put("password", "test123");
JSONObject response = restTemplate.postForObject(url.toString(), paramsMap, JSONObject.class);
System.out.println(response.toString());
4.设置参数(请求返回401)
RestTemplate restTemplate = new RestTemplate() ;
// //请求的url
String url = "http://172.16.60.111:3001/oauth/token" ;
//设置Http请求头和报文体
HttpHeaders httpHeaders = new HttpHeaders() ;
//设置HTTP请求的请求头信息
httpHeaders.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
//设置相应内容,相应内容将被转换为json格式返回
httpHeaders.setAcceptCharset(Collections.singletonList(Charset.forName("UTF-8")));
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
//创建要传递的对象
Map<String,Object> params = new HashMap<>();
params.put("grant_type", "password");
params.put("scope", "server");
params.put("client_id", "abc");
params.put("client_secret", "abc");
params.put("username", "test");
params.put("password", "test");
//设置HttpEntity的Body类型为String,调用StringHttpMessageConverter转换报文体参数
HttpEntity<String> httpEntity = new HttpEntity(params,httpHeaders) ;
//发送post请求,并将返回的实体类型设置的IndexInfo
restTemplate.postForObject(url, httpEntity, Object.class) ;
5.拦截器中放行(请求返回401)
参考链接:
SpringBoot 401 Unauthorized问题解决方案_指尖听戏的博客-CSDN博客_401 unauthorized
https://blog.csdn.net/qq_38140292/article/details/118926186WebSecurityConfigurerAdapter详解_wh柒八九的博客-CSDN博客_websecurityconfigureradapter
.authorizeRequests(); // 直接放行 .antMatchers("/auth/**", "/error/**", "/dev/**").permitAll() // 权限认证 .anyRequest().authenticated();
@Override
public void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry =
http.formLogin().successHandler(new HeavenLoginSuccessHandler())
.failureHandler(new HeavenLoginFailureHandler())
.loginPage(serverDomain + "/uauthentication/require/#/login")
.loginProcessingUrl("/uauthentication/form")
.and()
.authorizeRequests();
// // 直接放行
// .antMatchers("/**").permitAll()
// // 权限认证
// .anyRequest().authenticated();
http.logout().logoutUrl("/uauthentication/form/logout").addLogoutHandler(new HeavenLogoutHandler());
filterIgnorePropertiesConfig.getUrls().forEach(url -> registry.antMatchers(url).permitAll());
registry.anyRequest().authenticated()
.and()
.csrf().disable();
// http.apply(mobileSecurityConfigurer);
http.headers().frameOptions().disable(); // 允许前端VUE被frame加载
}
6.配置文件(请求返回401)
参考链接:Full authentication is required to access this resource解决办法_fds小哥的博客-CSDN博客
bootstrap中新增配置如下:
security:
basic:
enabled: false
7.Rest最终解决办法
也百度过其他方法,又说是clientId和clientSecret不对的问题,但是我这边肯定没问题的,如果也有小伙伴有问题,不妨都试试
参考链接:RestTemplate请求oauth获取token报401错误_weixin_43197042的博客-CSDN博客_oauthtoken获取失败
7.1原因:
参数的问题,将:
Map<String,Object> params = new HashMap<>();
改为:
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
7.2有效代码:
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.put("grant_type", Collections.singletonList("password"));
paramsMap.put("scope", Collections.singletonList("server"));
paramsMap.put("client_id", Collections.singletonList("abc"));
paramsMap.put("client_secret", Collections.singletonList("abc"));
paramsMap.put("username", Collections.singletonList("test"));
paramsMap.put("password", Collections.singletonList("test123"));
// JSONObject response = template.postForObject(url, paramsMap, JSONObject.class);
JSONObject response = restTemplate.postForObject(url.toString(), paramsMap, JSONObject.class);
System.out.println(response.toString());
System.out.println(response.get("access_token"));
7.3请求成功:
8.PostMan请求修改(有效)
一个大佬博客下的评论,我觉得就是这个原因导致的:
Spring Security Oauth2 认证(获取token/刷新token)流程(password模式)_昵称2021的博客-CSDN博客_oauth/check_token
将参数全部拼接在url后,请求成功
注意:此处的参数要改为下划线方式请求,驼峰式的依然会返回401
转载请注明:PostMan和RestTemplate请求/oauth/token获取token报401错误 | 胖虎的工具箱-编程导航