报错:

"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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐