为啥基本身份验证总是使用 restTemplate 给出错误 403?

Posted

技术标签:

【中文标题】为啥基本身份验证总是使用 restTemplate 给出错误 403?【英文标题】:Why the basic authentification gives always error 403 with restTemplate?为什么基本身份验证总是使用 restTemplate 给出错误 403? 【发布时间】:2019-10-27 00:54:31 【问题描述】:

我尝试了多种方法在spring boot项目中通过RestTemplate调用get url来获取json,但每次我得到以下403错误:

  <200,"request":"mbean":"org.apache.activemq.artemis:address=%22my.queue.demo%22,broker=%22141.110.112.13%22,component=addresses,queue=%22my.queue.demo%22,routing-type=%22anycast%22,subcomponent=queues","attribute":"MessageCount","type":"read","error_type":"java.lang.Exception","error":"java.lang.Exception
 : Reading attribute MessageCount is forbidden for MBean
 org.apache.activemq.artemis:address=%22my.queue.demo%22,broker=%22141.110.112.13%22,component=addresses,queue=%22my.queue.demo%22,routing-type=%22anycast%22,subcomponent=queues","status":403,[Date:"Wed,
 12 Jun 2019 12:56:22 GMT", Cache-Control:"no-cache",
 Pragma:"no-cache", Access-Control-Allow-Origin:"*",
 X-Frame-Options:"SAMEORIGIN", X-XSS-Protection:"1",
 Content-Type:"text/plain;charset=utf-8", Expires:"Wed, 12 Jun 2019
 11:56:22 GMT", Transfer-Encoding:"chunked"]>

这是我尝试调用的网址:

http://10.185.148.153:1495/console/jolokia/read/org.apache.activemq.artemis:broker=%22141.110.112.13%22,component=addresses,address=%22my.queue.demo%22,subcomponent=queues,routing-type=%22anycast%22,queue=%22my.queue.demo%22/MessageCount

当我使用 Postman 进行基本身份验证(用户 = 测试,通过 = 测试)时,它可以查找但不能用于 Resttemplate。

这是我的配置类:

@SpringBootApplication
public class StartWebApplication 

    public static void main(String[] args) 
        SpringApplication.run(StartWebApplication.class, args);
    


@Configuration
class Appconfig
    @Bean
    public RestTemplate restTemplate() 
        return new RestTemplate();
    

我的控制器:

...
@Autowired
private RestTemplate restTemplate;

....
restTemplate.exchange(url, HttpMethod.GET, createHeaders("test", "test"), String.class)
....
HttpEntity createHeaders(String username, String password) 
        byte[] token = Base64.getEncoder().encode(
                (username + ":" + password).getBytes());
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + new String(token));
        HttpEntity<String> request = new HttpEntity<>(headers);
        return request;
    

【问题讨论】:

您使用的是什么版本的 Spring?我问是因为 5.1 引入了一个 setter 方法,HttpHeaders#setBasicAuth,您可能会觉得它很有用。 我也遇到过,但我遇到了同样的错误 【参考方案1】:

使用RestTemplate,您可以避免一些Base64 样板:

@Bean
RestTemplate rest() 
    RestTemplate rest = new RestTemplate();
    rest.getInterceptors().add(new BasicAuthenticationInterceptor("test", "test"));
    return rest;

那么你可以简单地做:

rest.getForObject(url, String.class);

不确定问题是否出在您的用户名和密码的 Base64-ing 中,但这样做会消除这种可能性。

【讨论】:

BasicAuthorizationInterceptor 类型已被弃用,但我也尝试过它,但是我遇到了同样的 403 错误! 哎呀,我的意思是 BasicAuthenticationInterceptor。我已经更新了答案。 那么,可能还有其他事情正在发生。您能否以某种方式确认信用确实已添加到请求中?您能否将邮递员发送的授权标头与您的应用程序发送的授权标头进行比较?【参考方案2】:

你可以试试:

String auth = username + ":" + password;
byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
headers.add("Authorization", "Basic " + new String(encodedAuth));

【讨论】:

我也尝试过该解决方案,但我收到了相同的消息错误!【参考方案3】:

你可以试试这个解决方案:

1/ 您的用户名/密码不正确:

使用以下方式配置 J4pClient 客户端:

J4pClient 
    .url(JOLOKIA_URL) 
    .user(USERNAME) 
    .password(PASSWORD) 
    .authenticator(new BasicAuthenticator().preemptive()) 
    .build();

pom.xml 示例:

<dependency>
    <groupId>org.jolokia</groupId>
    <artifactId>jolokia-client-java</artifactId>
    <version>$jolokia-client-java.version</version>
</dependency>

2/ JMS Broker 不允许您访问给定的属性或 CORS 问题:

请看这里:https://jolokia.org/reference/html/security.html 如何配置 jolokia。例如。为 AcviveMQ Artemis 配置 etc/jolokia-access.xml。

【讨论】:

用户正在使用带有RestTemplate 的 Spring 建议放弃它并使用其他东西并不能真正解决问题。 @M.Deinum 你是对的。也许其他人会觉得它有帮助。

以上是关于为啥基本身份验证总是使用 restTemplate 给出错误 403?的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring restTemplate 对 REST API 进行基本身份验证

使用restTemplate发送带有身份验证标头的GET请求

为啥我在使用 RestTemplate 获取数据时总是得到 403? [复制]

outlook为啥总是验证身份失败?

使用 oAuth 和 youtube 进行身份验证时,总是出现错误:invalid_grant on 2nd auth attempt,为啥?

为啥在 Django 中需要基本或摘要式身份验证?