java - 将访问令牌存储在 OAuth2.0 应用程序中并重复使用直到过期?
问题描述
我正在开发一个调用一些 API(由 oauth2.0 保护)的 OAuth2.0“客户端”应用程序。我正在使用 OAuth2.0RestTemplate,其中包含 CLIENT_ID、CLIENT_SECRET、用户名和密码。调用 OAuth2.0 安全 API 的代码如下所示:
@Bean
OAuth2ProtectedResourceDetails resource() {
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
List<String> Scopes = new ArrayList<String>(2);
Scopes.add("read");
Scopes.add("write");
resource.setClientAuthenticationScheme(AuthenticationScheme.header);
resource.setId("*****");
resource.setAccessTokenUri(tokenUrl);
resource.setClientId("*****");
resource.setClientSecret("*****");
resource.setGrantType("password");
resource.setScope(Scopes);
resource.setUsername("*****");
resource.setPassword("*****");
return resource;
}
@Autowired
private OAuth2RestTemplate restTemplate;
Map<String, String> allCredentials = new HashMap<>();
allCredentials.put("username", "***");
allCredentials.put("password", "***");
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().setAll(allCredentials);
ParameterizedTypeReference<List<MyObject>> responseType = new ParameterizedTypeReference<List<MyObject>>() { };
ResponseEntity<List<MyObject>> response = restTemplate.exchange("https://***.*****.com/api/*****/*****",
HttpMethod.GET,
null,
responseType);
AllCities all = new AllCities();
all.setAllCities(response.getBody());
正如您所看到的,每次我想调用服务时,代码都会得到一个新的访问令牌,这是非常错误的!!!我的问题是如何在我的应用程序中自动接收和存储颁发的令牌并使用它直到它过期然后自动获取一个新的?另一方面,我的令牌只包含访问令牌,不包含刷新令牌(我不知道为什么!!!这太奇怪了!!!)
解决方案
你好,你可以像谷歌客户端库一样设计。第一步,您需要创建数据存储以将令牌存储
在您的目录中,例如 C:/User/soyphea/.token/datastore。
在加载函数之前检索 access_token_store。您的访问令牌应该已过期_in。
if(access_token_store from your datastore !=null && !expired){
access_token = access_token_store.
} else {
access_token = Your RestTemplate function for retrieve access_token.
}
最后,您可以检索 access_token。
在 spring security oauth2 中如果你想支持 refresh_token 你需要设置,
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("resource-serv")
.scopes("read")
.resourceIds("my-resource")
.secret("secret123")
.and()
.withClient("app")
.authorizedGrantTypes("client_credentials", "password", "refresh_token")
.scopes("read")
.resourceIds("my-resource")
.secret("appclientsecret");
}
推荐阅读
- c# - Xamarin android 应用程序崩溃,条件为 `xref_count == xref_index' 未满足
- asp.net - 单个视图页面中的多个表 Asp.net 4
- python - Dask 如何决定是否重新运行任务
- css - 选择具有子项的第一个子列表项
- javafx - 如何摆脱 JavaFX / TornadoFX 中饼图与其边框之间的额外空间(填充)?
- python - Discord.py @bot.event
- domain-driven-design - 域服务可以注入多个存储库或使用不同的聚合根进行操作吗?
- sharepoint - Spotfire 可以根据用户名更改数据表源目录吗?
- python-3.x - 如何根据 Python Pandas 中另一列的前一行值和值填充后续行?
- elasticsearch - 如何将 Slack 集成添加到弹性云的密钥库