Spring OAuth2 – 在令牌存储中手动创建访问令牌

我有一种情况,我想自己创建一个访问令牌(所以不通过通常的过程)。 我想出了这样的事情:

@Inject private DefaultTokenServices defaultTokenServices; ... OAuth2Authentication auth = xxx; OAuth2AccessToken token = defaultTokenServices.createAccessToken(auth); 

唯一的问题是我不知道如何创建OAuth2Authentication(在我的代码中使用xxx的部分)。 我有用户和客户信息,我知道我想授予此令牌的权限。

在这里,您的使用案例可能会根据您使用的流程略有不同。 这适用于密码授予流程。 有一些自定义类,如令牌存储,令牌增强等。 但这只是为了我们自己的需要而修改的弹簧类的扩展版本。

  HashMap authorizationParameters = new HashMap(); authorizationParameters.put("scope", "read"); authorizationParameters.put("username", "mobile_client"); authorizationParameters.put("client_id", "mobile-client"); authorizationParameters.put("grant", "password"); DefaultAuthorizationRequest authorizationRequest = new DefaultAuthorizationRequest(authorizationParameters); authorizationRequest.setApproved(true); Set authorities = new HashSet(); authorities.add(new SimpleGrantedAuthority("ROLE_UNTRUSTED_CLIENT")); authorizationRequest.setAuthorities(authorities); HashSet resourceIds = new HashSet(); resourceIds.add("mobile-public"); authorizationRequest.setResourceIds(resourceIds); // Create principal and auth token User userPrincipal = new User(user.getUserID(), "", true, true, true, true, authorities); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userPrincipal, null, authorities) ; OAuth2Authentication authenticationRequest = new OAuth2Authentication(authorizationRequest, authenticationToken); authenticationRequest.setAuthenticated(true); CustomTokenStore tokenStore = new CustomTokenStore(); // Token Enhancer CustomTokenEnhancer tokenEnhancer = new CustomTokenEnhancer(user.getUserID()); CustomTokenServices tokenServices = new CustomTokenServices(); tokenServices.setTokenEnhancer(tokenEnhancer); tokenServices.setSupportRefreshToken(true); tokenServices.setTokenStore(tokenStore); OAuth2AccessToken accessToken = tokenServices.createAccessTokenForUser(authenticationRequest, user); 

以下是如何使用TokenEndpoint接口生成令牌(用于公开REST服务):

 @Inject private TokenEndpoint tokenEndpoint; public ResponseEntity getToken(Principal principal) { HashMap parameters = new HashMap(); parameters.put("client_id", "appid"); parameters.put("client_secret", "myOAuthSecret"); parameters.put("grant_type", "password"); parameters.put("password", myUser.getPassword()); parameters.put("scope", "read write"); parameters.put("username", myUser.getLogin()); return tokenEndpoint.getAccessToken(principal, parameters); } 

OAuth2 Accesss Token ,要手动生成OAuth2 Accesss Token我们可以使用TokenService的实例

 @Autowired private AuthorizationServerEndpointsConfiguration configuration; @Override public String generateOAuth2AccessToken(User user, List roles, List scopes) { Map requestParameters = new HashMap(); Map extensionProperties = new HashMap(); boolean approved = true; Set responseTypes = new HashSet(); responseTypes.add("code"); // Authorities List authorities = new ArrayList(); for(Role role: roles) authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName())); OAuth2Request oauth2Request = new OAuth2Request(requestParameters, "clientIdTest", authorities, approved, new HashSet(scopes), new HashSet(Arrays.asList("resourceIdTest")), null, responseTypes, extensionProperties); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), "N/A", authorities); OAuth2Authentication auth = new OAuth2Authentication(oauth2Request, authenticationToken); AuthorizationServerTokenServices tokenService = configuration.getEndpointsConfigurer().getTokenServices(); OAuth2AccessToken token = tokenService.createAccessToken(auth); return token.getValue(); } 

这对我有用:

 @Override public OAuth2AccessToken getToken(String username, String password) { HashMap parameters = new HashMap(); parameters.put("client_id", clientid); parameters.put("grant_type", "password"); parameters.put("password", username); parameters.put("scope", scope); parameters.put("username", password); AuthorizationRequest authorizationRequest = defaultOAuth2RequestFactory.createAuthorizationRequest(parameters); authorizationRequest.setApproved(true); OAuth2Request oauth2Request = defaultOAuth2RequestFactory.createOAuth2Request(authorizationRequest); // Create principal and auth token final UsernamePasswordAuthenticationToken loginToken = new UsernamePasswordAuthenticationToken( username, password); Authentication authentication = authenticationManager.authenticate(loginToken); OAuth2Authentication authenticationRequest = new OAuth2Authentication(oauth2Request, authentication); authenticationRequest.setAuthenticated(true); OAuth2AccessToken accessToken = tokenServices.createAccessToken(authenticationRequest); return accessToken; } 

在Oauth2Configuration中:

 @Bean DefaultOAuth2RequestFactory defaultOAuth2RequestFactory() { return new DefaultOAuth2RequestFactory(clientDetailsService); } 

Oauth2Configuration的其余部分应如下文所示:

http://stytex.de/blog/2016/02/01/spring-cloud-security-with-oauth2/

我的解决方案基于Mop So的答案,但不是使用:

 return tokenEndpoint.getAccessToken(principal, parameters); 

我用了:

 tokenEndpoint.postAccessToken(principal, parameters); 

为什么? 因为如果使用tokenEndpoint.getAccessToken(principal, parameters) ,endpoing将抛出HttpRequestMethodNotSupportedException因为它尚未使用GET方法调用。 至少,这是我在spring-security-oauth2-2.0.13.RELEASE发生的事情

 public OAuth2AccessToken getAccessToken() throws HttpRequestMethodNotSupportedException { HashMap parameters = new HashMap<>(); parameters.put("client_id", CLIENT_ID); parameters.put("client_secret", CLIENT_SECRET); parameters.put("grant_type", "client_credentials"); ClientDetails clientDetails = clientDetailsStore.get(CLIENT_ID); // Create principal and auth token User userPrincipal = new User(CLIENT_ID, CLIENT_SECRET, true, true, true, true, clientDetails.getAuthorities()); UsernamePasswordAuthenticationToken principal = new UsernamePasswordAuthenticationToken(userPrincipal, CLIENT_SECRET, clientDetails.getAuthorities()); ResponseEntity accessToken = tokenEndpoint.postAccessToken(principal, parameters); return accessToken.getBody(); }