有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

oauth 2.0 Microsoft Graph和Java针对授权代码流的多次调用

几个小时来我一直在想这个问题,现在我在兜圈子,浪费时间。我正在使用MS Graph API访问Office 365,我已经使用授权流对其进行了设置,以授权我的Java servlet。它工作正常(获取身份验证代码的URL在别处),但我只能运行一个调用。我在后续调用的异常中得到以下错误(在我的代码中,是在我尝试查看驱动器时):

OAuth2授权代码已兑换,请使用新的有效代码重试,或使用现有的刷新令牌

我假设这意味着我需要刷新我的令牌(很明显,我已经找到了关于这一点的注释,说明它现在在这个流程中是必要的),但我不知道如何使用GraphServiceClient来完成

下面是我的代码,在我将笔记本电脑从最近的窗口飞盘出去之前,任何帮助都将是最受欢迎的

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        PrintWriter out = response.getWriter();

        String code = request.getParameter("code");

        String clientId = "***";
        String clientSecret = "***";
        String authorisationCode = code; 
        String redirectURL = "http://localhost:8080/O365Web/auth";
        String tenant = "***";

        AuthorizationCodeCredential authCodeCredential = new AuthorizationCodeCredentialBuilder()
                .clientId(clientId)
                .clientSecret(clientSecret) //required for web apps, do not set for native apps
                .authorizationCode(authorisationCode)
                .redirectUrl(redirectURL)               
                .build();

        List<String> scopes = new ArrayList<String>();
        scopes.add("https://graph.microsoft.com/User.Read");
        scopes.add("https://graph.microsoft.com/Files.ReadWrite.All");
        scopes.add("https://graph.microsoft.com/offline_access");

        TokenCredentialAuthProvider tokenCredentialAuthProvider = new TokenCredentialAuthProvider(scopes, authCodeCredential);      

        GraphServiceClient graphClient =
                GraphServiceClient
                .builder()              
                .authenticationProvider(tokenCredentialAuthProvider)                
                .buildClient();

        try {
            final User me = graphClient.me().buildRequest().get();
            out.println("Name: " + me.displayName + "");
        } catch ( Exception ex ) {
            out.println("Exception in first user get: " + ex.getMessage() );    
            ex.printStackTrace();
        }

        try {
            DriveItemCollectionPage children = graphClient.me().drive().root().children().buildRequest().get();

            while ( children != null ) {

                for ( DriveItem item : children.getCurrentPage() ) {
                    out.println("C:" + item.name + " : " + item.id);
                }

                DriveItemCollectionRequestBuilder builder = children.getNextPage();
                if ( builder != null ) {
                    out.println("Loading page...");
                    children = children.getNextPage().buildRequest().get();
                } else {
                    children = null;
                }
            }
        } catch ( Exception ex ) {
            out.println("Exception in children get: " + ex.getMessage());   
            ex.printStackTrace();
        }

        try {
            final User me2 = graphClient.me().buildRequest().get();
            out.println(me2.displayName + "<br/>");
        } catch ( Exception ex ) {
            out.println("Exception in second user get: " + ex.getMessage());    
            ex.printStackTrace();
        }
    }

共 (1) 个答案

  1. # 1 楼答案

    我已经在我的环境中进行了测试

    当我第一次运行请求时,我能够生成访问令牌

    当我再次运行相同的请求时,我也得到了相同的错误:

    OAuth2授权码已兑换,请使用新的有效码重试,或使用现有的刷新令牌

    错误原因是AuthCodeRedential中使用的授权代码只能使用一次

    String authorisationCode = code; 
    

    如果您想发出新请求,可以生成新的授权码(获取授权码的URL在别处),并在AuthCodeRedential中使用它

    这可以解决这个问题

    另一种方法是使用刷新令牌

    在使用URL生成授权代码时,您可以使用离线访问添加另一个作用域

    现在,在使用授权代码生成访问令牌的同时,添加另一个具有脱机访问的作用域。 这将生成一个刷新令牌和访问令牌

    现在,当访问令牌过期时,可以使用刷新令牌生成新的访问令牌

    参考:Get access on behalf of a user - Microsoft Graph | Microsoft Docs