spring-security Spring Boot :当令牌也来自调用另一个API时,在rest API的请求标头中进行令牌身份验证(承载)

0aydgbwb  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(139)

在我的Spring Boot 应用程序中,我有一个调度程序,它调用一个API来生成令牌,令牌在15分钟内到期。调度程序的时间也是15分钟。请查看以下示例:

public class TokenGeneration {
    private static String token = null;

    @Scheduled(15 minutes)
    public String fetchToken() {
        // api call which return token
        HttpEntity<model> response = restTemplate.exchange(uri, POST, entity, model.class);
        token = response.getBody().getAccessToken();
    }
 }

我从一个非静态的方法中将令牌值存储在静态变量中,这样我就可以在任何我想使用令牌值的地方使用这个令牌变量。这是正确的方法吗?如果不是,请让我知道我如何才能做到这一点。
我是否需要使TokenGeneration类成为singleton,以便在整个应用程序中只生成该类的一个示例?
我还想创建一个拦截器或过滤器,我可以在其中设置授权头和令牌值,以便每个请求将自动填充授权头,我不想在每个请求中设置授权头,如下所示:

HttpHeaders headers = new HttpHeaders();
    headers.set(CpsConstant.AUTHORIZATION, CpsConstant.BEARER + token);

所以我尝试使用这个自定义拦截器:

public class RestTemplateInterceptor implements ClientHttpRequestInterceptor{

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {

     String token = TokenGeneration.token;
     request.getHeaders().add("Authorization", "Bearer " + token);    
     return execution.execute(request, body);
}

将在配置文件的restTemplate中添加此侦听器。
那么,这种方法对于令牌生成以及为每个请求设置头是否正确,或者这种方法是否需要进行任何改进?我考虑在令牌为空的情况下调用拦截器中的令牌生成方法,如:

if(token == null){
//call token generation fetchToken method 
}
wbgh16ku

wbgh16ku1#

1.这是正确的方法
1.如果未指定,Spring默认范围始终为singleton
1.使用拦截器是可以的,但是如果您想在没有令牌的情况下调用API,该怎么办?
最好的方法是使用两个单独的方法,使用单独的类发送带标记和不带标记的请求

@Component
public class RestClient {

@Autowired
RestTemplate restTemplate;

public HttpHeaders getRequestHeaderBearer() {

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);
headers.add(HeaderParameters.AUTHORIZATION, HeaderParameters.BEARER + 
TokenGeneration.token);

return headers;

}

public HttpHeaders getRequestHeader() {

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);

return headers;

}

public <T> ResponseEntity<T> restExchangeBearer(String url, HttpMethod httpMethod,
    Class<T> classObj) {

return restTemplate.exchange(url, httpMethod,
    new HttpEntity<>("parameters", this.getRequestHeaderBearer()), classObj);

}

public <T> ResponseEntity<T> restExchange(String url, HttpMethod httpMethod,
    Class<T> classObj) {

return restTemplate.exchange(url, httpMethod,
    new HttpEntity<>("parameters", this.getRequestHeader()), classObj);

}
}

相关问题