Spring boot 生成OAuth2访问令牌,并对JUnit测试进行其他声明
我使用OAuth2保护了SpringBootRESTAPI。我的身份验证服务器和资源服务器是两个应用程序。所有REST API安全性都能与REST客户端正常工作。 然后我需要编写安全测试用例。我使用以下代码生成访问令牌。某些端点需要在REST方法中手动添加声明。 程序提供了有效的访问令牌,但声明未包含在此令牌中Spring boot 生成OAuth2访问令牌,并对JUnit测试进行其他声明,spring-boot,spring-security-oauth2,spring-security-test,Spring Boot,Spring Security Oauth2,Spring Security Test,我使用OAuth2保护了SpringBootRESTAPI。我的身份验证服务器和资源服务器是两个应用程序。所有REST API安全性都能与REST客户端正常工作。 然后我需要编写安全测试用例。我使用以下代码生成访问令牌。某些端点需要在REST方法中手动添加声明。 程序提供了有效的访问令牌,但声明未包含在此令牌中 private String generateToken(String... authorities) { JwtAccessTokenConverter converter
private String generateToken(String... authorities) {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
tokenService = new DefaultTokenServices();
JwtTokenStore jwtTokenStore = new JwtTokenStore(converter);
tokenService.setTokenStore(jwtTokenStore);
tokenService.setTokenEnhancer(converter);
Collection<GrantedAuthority> grantAuthorities = new ArrayList<>();
if (authorities != null) {
for (String authority: authorities) {
grantAuthorities.add(new SimpleGrantedAuthority(authority));
}
}
Set<String> resourceIds = Collections.emptySet();
Set<String> scopes = Collections.emptySet();
Map<String, String> requestParameters = Collections.emptyMap();
boolean approved = true;
String redirectUrl = null;
Set<String> responseTypes = Collections.emptySet();
Map<String, Serializable> extensionProperties = Collections.emptyMap();
OAuth2Request oAuth2Request = new OAuth2Request(requestParameters, "web-client", grantAuthorities,
approved, scopes, resourceIds, redirectUrl, responseTypes, extensionProperties);
User userPrincipal = new User("user", "", true, true,
true, true, grantAuthorities);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userPrincipal, null, grantAuthorities);
OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
OAuth2AccessToken accessToken = tokenService.createAccessToken(auth);
Map<String, Object> claims = new HashMap<>();
List<Long> tenantIds = new ArrayList<>();
tenantIds.add(1L);
claims.put("role", 1L);
claims.put("tenants", tenantIds);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(claims);
return accessToken.getValue();
}
private String generateToken(字符串…权限){
JwtAccessTokenConverter=新的JwtAccessTokenConverter();
转换器。设置点火键(“123”);
tokenService=新的DefaultTokenServices();
JwtTokenStore JwtTokenStore=新的JwtTokenStore(转换器);
setTokenStore(jwtTokenStore);
setTokenEnhancer(转换器);
集合授权=新建ArrayList();
如果(权限!=null){
for(字符串权限:权限){
增列(新的简化授权书(授权书));
}
}
Set resourceIds=Collections.emptySet();
Set scopes=Collections.emptySet();
Map requestParameters=Collections.emptyMap();
布尔批准=真;
字符串重定向URL=null;
Set responseType=Collections.emptySet();
Map extensionProperties=Collections.emptyMap();
OAuth2Request OAuth2Request=新的OAuth2Request(请求参数,“web客户端”,授权,
已批准、范围、资源ID、重定向URL、响应类型、扩展属性);
User userPrincipal=新用户(“用户”,true,true,
真的,真的,授权书);
UsernamePasswordAuthenticationToken authenticationToken=
新的UsernamePasswordAuthenticationToken(userPrincipal、null、grantAuthorities);
OAuth2Authentication auth=新的OAuth2Authentication(oAuth2Request,authenticationToken);
OAuth2AccessToken accessToken=tokenService.createAccessToken(auth);
Map claims=newhashmap();
List tenantitds=new ArrayList();
添加(1L);
索赔。投入(“角色”,1L);
索赔。出售(“承租人”,承租人);
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(声明);
返回accessToken.getValue();
}
如何将声明添加到此令牌。最终找到了解决方案。向代码中添加令牌增强码
private String generateToken(String... authorities) {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
tokenService = new DefaultTokenServices();
JwtTokenStore jwtTokenStore = new JwtTokenStore(converter);
tokenService.setTokenStore(jwtTokenStore);
tokenService.setTokenEnhancer(converter);
Collection<GrantedAuthority> grantAuthorities = new ArrayList<>();
if (authorities != null) {
for (String authority: authorities) {
grantAuthorities.add(new SimpleGrantedAuthority(authority));
}
}
Set<String> resourceIds = Collections.emptySet();
Set<String> scopes = Collections.emptySet();
Map<String, String> requestParameters = Collections.emptyMap();
boolean approved = true;
String redirectUrl = null;
Set<String> responseTypes = Collections.emptySet();
Map<String, Serializable> extensionProperties = Collections.emptyMap();
OAuth2Request oAuth2Request = new OAuth2Request(requestParameters, "web-client", grantAuthorities,
approved, scopes, resourceIds, redirectUrl, responseTypes, extensionProperties);
User userPrincipal = new User("user", "", true, true,
true, true, grantAuthorities);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userPrincipal, null, grantAuthorities);
OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
OAuth2AccessToken accessToken = tokenService.createAccessToken(auth);
Map<String, Object> claims = new HashMap<>();
List<Long> tenantIds = new ArrayList<>();
tenantIds.add(1L);
claims.put("role", 1L);
claims.put("tenants", tenantIds);
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(claims);
return accessToken.getValue();
}
以下是最终代码
private String generateToken(String... authorities) {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey("123");
tokenService = new DefaultTokenServices();
JwtTokenStore jwtTokenStore = new JwtTokenStore(converter);
tokenService.setTokenStore(jwtTokenStore);
Collection<GrantedAuthority> grantAuthorities = new ArrayList<>();
if (authorities != null) {
for (String authority: authorities) {
grantAuthorities.add(new SimpleGrantedAuthority(authority));
}
}
Set<String> resourceIds = Collections.emptySet();
Set<String> scopes = Collections.emptySet();
Map<String, String> requestParameters = Collections.emptyMap();
boolean approved = true;
String redirectUrl = null;
Set<String> responseTypes = Collections.emptySet();
Map<String, Serializable> extensionProperties = Collections.emptyMap();
OAuth2Request oAuth2Request = new OAuth2Request(requestParameters, "web-client", grantAuthorities,
approved, scopes, resourceIds, redirectUrl, responseTypes, extensionProperties);
User userPrincipal = new User("user", "", true, true,
true, true, grantAuthorities);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userPrincipal, null, grantAuthorities);
OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken);
Map<String, Object> claims = new HashMap<>();
List<Long> tenantIds = new ArrayList<>();
tenantIds.add(1L);
claims.put("role", 1L);
claims.put("tenants", tenantIds);
OAuth2AccessToken accessToken = tokenService.createAccessToken(auth);
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(new CustomTokenEnhancer(), converter));
accessToken = tokenEnhancerChain.enhance(accessToken, auth);
return accessToken.getValue();
}
private String generateToken(字符串…权限){
JwtAccessTokenConverter=新的JwtAccessTokenConverter();
转换器。设置点火键(“123”);
tokenService=新的DefaultTokenServices();
JwtTokenStore JwtTokenStore=新的JwtTokenStore(转换器);
setTokenStore(jwtTokenStore);
集合授权=新建ArrayList();
如果(权限!=null){
for(字符串权限:权限){
增列(新的简化授权书(授权书));
}
}
Set resourceIds=Collections.emptySet();
Set scopes=Collections.emptySet();
Map requestParameters=Collections.emptyMap();
布尔批准=真;
字符串重定向URL=null;
Set responseType=Collections.emptySet();
Map extensionProperties=Collections.emptyMap();
OAuth2Request OAuth2Request=新的OAuth2Request(请求参数,“web客户端”,授权,
已批准、范围、资源ID、重定向URL、响应类型、扩展属性);
User userPrincipal=新用户(“用户”,true,true,
真的,真的,授权书);
UsernamePasswordAuthenticationToken authenticationToken=
新的UsernamePasswordAuthenticationToken(userPrincipal、null、grantAuthorities);
OAuth2Authentication auth=新的OAuth2Authentication(oAuth2Request,authenticationToken);
Map claims=newhashmap();
List tenantitds=new ArrayList();
添加(1L);
索赔。投入(“角色”,1L);
索赔。出售(“承租人”,承租人);
OAuth2AccessToken accessToken=tokenService.createAccessToken(auth);
TokenEnhancerCain TokenEnhancerCain=新的TokenEnhancerCain();
TokenEnhancerCain.setTokenEnhancers(
asList(新的CustomTokenEnhancer(),converter));
accessToken=TokenEnhancerCain.enhance(accessToken,auth);
返回accessToken.getValue();
}
重要提示:添加JwtAccessTokenConverter作为令牌增强器列表的最后一个元素
下面是CustomTokenEnhancer类
public class CustomTokenEnhancer extends JwtAccessTokenConverter {
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
Map<String, Object> claims = new HashMap<>();
List<Long> tenantIds = new ArrayList<>();
tenantIds.add(1L);
claims.put("role", 1L);
claims.put("tenants", tenantIds);
claims.put("userId", "admin@abc.com");
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(claims);
return accessToken;
}
}
公共类CustomTokenEnhancer扩展了JwtAccessTokenConverter{
@凌驾
公共OAuth2AccessToken增强(OAuth2AccessToken accessToken,OAuth2Authentication身份验证){
Map claims=newhashmap();
List tenantitds=new ArrayList();
添加(1L);
索赔。投入(“角色”,1L);
索赔。出售(“承租人”,承租人);
claims.put(“userId”admin@abc.com");
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(声明);
返回accessToken;
}
}
您所说的“索赔”是什么意思?是大权威吗?不是授予权威。他们很好。但其他参数,如“角色”、“租户”等。如果您获得一些令牌,如aaaaaa1
,并且您想在此处添加一些role
如admin
,则具有新声明的新令牌将不会是aaaa1
。所以,您需要生成一次令牌,其中包含所有信息,令牌不需要修改就可以生存。查看JWT,您可以在其中存储有关用户的payload
数据。是否有任何方法可以一次性生成带有声明的令牌。查看您的OAuth2AccessToken accessToken=tokenService.createAccessToken(auth)代码>代码行。检查createAccessToken
方法,并进行修改,以在您的令牌中添加声明什么是DefaultTokenServices
?如何OAuth2Request
行为?OAuth2Authentication
如何工作以及在何处进行身份验证?在建议的答案中,您可以说,只需添加tokenEnhancerChain