来自Spring安全上下文的无效的oAuth访问令牌

问题描述

我正在尝试将Spring Boot应用程序与Azure AD集成以进行身份​​验证,然后访问图形api来检索用户图片

我的Spring引导安全性配置是这样的:

@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

 @Autowired
 private AADAuthenticationProperties aadAuthProps;

 @Autowired
 private ServiceEndpointsProperties serviceEndpointsProps;

 @Override
 protected void configure(HttpSecurity http) throws Exception {
  http
     .authorizeRequests()
     .anyRequest().authenticated()
     .and()
     .oauth2Login();
 }

 @Bean
 protected OAuth2UserService<OidcUserRequest,OidcUser> customADOAuth2UserService() {
  return new CustomADOAuth2UserService(aadAuthProps,serviceEndpointsProps);
 }
}

登录非常有效:当我访问Web应用程序时,spring将我重定向登录页面,并且在进行身份验证之后,我可以访问该应用程序的资源。到目前为止一切顺利。

但是,当我随后访问旨在将用户数据(名称,电子邮件图片)返回给客户端的REST服务时,一切都会失败。

其余的失败服务是这样的:

@RestController
@RequestMapping("/rest/users")
public class UserResource {

 @Autowired
 OAuth2AuthorizedClientService clientService;

 @GetMapping("current")
 public UserTo getCurrentUser@R_399_4045@ion() throws IOException {
   OAuth2AuthenticationToken auth = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
   OAuth2AuthorizedClient client = clientService.loadAuthorizedClient(auth.getAuthorizedClientRegistrationId(),auth.getName());
   String accesstoken = client.getAccesstoken().getTokenValue();
   UserTo user = new UserTo(auth.getName());
   URL url = new URL("https://graph.microsoft.com/v1.0/me/photo/$value");
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   conn.setRequestProperty("Authorization","Bearer " + accesstoken);
   conn.setRequestProperty("Accept","application/json");
   String response = getResponseStringFromConn(conn);
   user.setPicData(response);
   int responseCode = conn.getResponseCode();
   if(responseCode != HttpURLConnection.HTTP_OK) { throw new IOException(response); }
   return user;
  }

 private String getResponseStringFromConn(HttpURLConnection conn) throws IOException {
   int responseCode = conn.getResponseCode();
   BufferedReader br = new BufferedReader(
      responseCode > 299 ? new InputStreamReader((conn.getErrorStream())) : new InputStreamReader((conn.getInputStream())));
   String output = "";
   String s = br.readLine();
    while (s != null) {
      output += s;
      s= br.readLine();
    }
  return output;
}}

对Microsoft graph API的调用失败,并出现以下错误

{"error": {    
   "code": "InvalidAuthenticationToken","message": "CompactToken parsing Failed with error code: 80049217","innerError": {      
     "date": "2020-09-09T21:57:15","request-id": "9255169d-58a7-47c0-9bdb-1a05de6c220d"    
    }  
}}

我如何从Spring安全上下文中提取访问令牌似乎有问题,但是我不知道该怎么办。有人有想法吗?

谢谢!

PS:为完整起见,CustomADOAuth2UserService如下:

public class CustomADOAuth2UserService implements OAuth2UserService<OidcUserRequest,OidcUser> {

    AADOAuth2UserService aadoAuth2UserService;

    public CustomADOAuth2UserService(AADAuthenticationProperties aadAuthProps,ServiceEndpointsProperties serviceEndpointsProps) {
        aadoAuth2UserService = new AADOAuth2UserService(aadAuthProps,serviceEndpointsProps);
    }

    @Override
    public OidcUser loadUser(OidcUserRequest userRequest) throws OAuth2AuthenticationException {
        OidcUser user = aadoAuth2UserService.loadUser(userRequest);
        Set<GrantedAuthority> mappedAuthorities = new HashSet<>(user.getAuthorities());
        String userName = (String) user.getIdToken().getClaims().get("unique_name");
        return new DefaultOidcUser(mappedAuthorities,user.getIdToken(),this.getUserNameAttrName(userRequest));
    }

    private String getUserNameAttrName(OAuth2UserRequest userRequest) {
        String userNameAttrName = userRequest.getClientRegistration()
                .getProviderDetails()
                .getUserInfoEndpoint()
                .getUserNameAttributeName();
        if (StringUtils.isEmpty(userNameAttrName)) {
            userNameAttrName = "name";
        }
        return userNameAttrName;
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)