2017-09-05 80 views
0
  • 400錯誤的請求的代碼似乎並沒有任何錯誤。
  • 這是一個測試應用程序,所有的ID都可用。
  • 在函數爲gettoken()一個可替代疏通線呼叫爲 getScopes(),並進一步嘗試。
  • 我有一個按鈕的index.jsp。
  • 在按下按鈕「oauthorize」被激活以生成代碼和id_token。
  • 我能夠登錄,生成的代碼和id_token。
  • 這些值顯示在其上有一個按鈕一個「authtoken.jsp」。
  • 按鈕按職位,/common/oauth2/v2.0/token。
  • 在這個階段,400頁的錯誤請求會顯示在Microsoft頁面上。

我不知道是怎麼回事錯誤:的訪問令牌的Outlook API返回的Java春

import java.util.UUID; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import javax.servlet.http.HttpServletResponse; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.util.UriComponentsBuilder; 


@Controller 
public class IndexController { 

    //all oauth2 urls 
    private static final String authority = "https://login.microsoftonline.com"; 
    private static final String authorizeUrl = authority + "/common/oauth2/v2.0/authorize"; 
    private static final String tokenUrl = authority + "/common/oauth2/v2.0/token"; 
    private static final String redirectUrl = "http://localhost:8080/OutlookProfiles/authtoken"; 
    private static final String reTokenUrl = "http://localhost:8080/OutlookProfiles/showToken"; 

    //credentials 
    private static final String appId = "7414b3a3-26f1-4928-9d0b-7060d01dd41c"; 
    private static final String appPassword = "cQg9F0EaxuaErNp2YEgYaz8"; 

    private static final String[] scopes = { 
       "openid", 
       "offline_access", 
       "profile", 
       "User.Read", 
       "Contacts.Read", 
       "Mail.Read" 
       }; 


    @RequestMapping(value = "/index", method = RequestMethod.GET) 
    public String index(Model model, HttpServletRequest request, HttpServletResponse response){ 

     UUID state = UUID.randomUUID(); 
     UUID nonce = UUID.randomUUID(); 

     // Save the state and nonce in the session so we can 
     // verify after the auth process redirects back 

     HttpSession session = request.getSession(); 
     session.setAttribute("expected_state", state); 
     session.setAttribute("expected_nonce", nonce); 

     return "index"; 
    } 

    @RequestMapping(value = "/oauthorize", method = RequestMethod.POST) 
    public void oauthorize(Model model, HttpServletRequest servletRequest, HttpServletResponse servletResponse) { 

     try{ 

     UUID state = UUID.randomUUID(); 
     UUID nonce = UUID.randomUUID(); 

      HttpSession session = servletRequest.getSession(); 
      session.setAttribute("expected_state", state); 
      session.setAttribute("expected_nonce", nonce); 
      session.setAttribute("error", null); 

     UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(authorizeUrl); 
     urlBuilder.queryParam("client_id", appId); 
     urlBuilder.queryParam("redirect_uri", redirectUrl); 
     urlBuilder.queryParam("response_type", "code id_token"); 
     urlBuilder.queryParam("scope", getScopes()); 
     urlBuilder.queryParam("state", state); 
     urlBuilder.queryParam("nonce", nonce); 
     urlBuilder.queryParam("response_mode", "form_post"); 

     String locationUri = urlBuilder.toUriString(); 
     System.out.println(locationUri); 

     servletResponse.sendRedirect(locationUri); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 


    @RequestMapping(value = "/authtoken", method = RequestMethod.POST) 
    public String authorize(
       @RequestParam("code") String code, 
       @RequestParam("id_token") String idToken, 
       @RequestParam("state") UUID state, 
       HttpServletRequest servletRequest, 
       HttpServletResponse servletResponse) { 

     // Get the expected state value from the session 
     HttpSession session = servletRequest.getSession(); 
     UUID expectedState = (UUID) session.getAttribute("expected_state"); 
     UUID expectedNonce = (UUID) session.getAttribute("expected_nonce"); 


     String strState = state.toString().trim().toLowerCase(); 
     String strExState = expectedState.toString().trim().toLowerCase(); 


     // Make sure that the state query parameter returned matches 
     // the expected state 
     if (strState.equals(strExState)){ 
      session.setAttribute("authCode", code); 
      session.setAttribute("idToken", idToken); 
      System.out.println("Expectedstate : NO Error"); 
     }else { 
      session.setAttribute("error", "Unexpected state returned from authority."); 
      System.out.println("\n\nUnexpected state returned from authority."); 
     } 

     return "authtoken"; 
    } 

    @RequestMapping(value = "/getToken", method = RequestMethod.POST) 
    public void getToken(
      HttpServletRequest servletRequest, 
      HttpServletResponse servletResponse) { 

     try{ 

     HttpSession session = servletRequest.getSession(); 
     String strCode = (String) session.getAttribute("authCode"); 

     UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(tokenUrl); 
     urlBuilder.queryParam("client_id", appId); 
     urlBuilder.queryParam("client_secret", appPassword); 
     urlBuilder.queryParam("code", strCode); 
     urlBuilder.queryParam("redirect_uri", redirectUrl); 
     urlBuilder.queryParam("grant_type", "authorization_code"); 
     urlBuilder.queryParam("scope", getScopes()); 

     String locationUri = urlBuilder.toUriString(); 
     System.out.println("getToken : " + locationUri); 

     servletResponse.setHeader("Content-Type", "application/x-www-form-urlencoded"); 

     servletResponse.sendRedirect(locationUri); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    @RequestMapping(value = "/showToken", method = RequestMethod.POST) 
    public String showToken(
      @RequestParam("token_type") String code, 
      @RequestParam("expires_in") String idToken, 
      @RequestParam("access_token") String accessToken, 
      //@RequestParam("scope") String paramScope, 
      HttpServletRequest servletRequest, 
      HttpServletResponse servletResponse) { 

     return "getToken"; 

    } 

    @RequestMapping("/logout") 
    public String logout(HttpServletRequest request) { 
     HttpSession session = request.getSession(); 
     session.invalidate(); 
     return "index"; 
    } 

    private static String getScopes() { 
      StringBuilder sb = new StringBuilder(); 
      for (String scope: scopes) { 
       sb.append(scope + " "); 
      } 

      String strscope = sb.toString().trim(); 
      System.out.println(strscope); 

      return strscope; 
    } 
} 

400錯誤是我的頭無故搞亂。

+1

我沒有看到鞦韆的任何使用在你的代碼。你是說春天嗎? – pcarter

+0

謝謝卡特。我修正了從Swing到Spring的錯字。 –

回答

0
  • Microsoft Outlook的API結束點訪問令牌:https://login.microsoftonline.com/common/oauth2/v2.0/token 期望一個形式的基於POST即應用/ X WWW的窗體-urlencoded。
  • 這意味着所有的輸入參數應根據是形式,而不是URL附加
  • 所以技術上的編碼是錯誤的使用UriComponentsBuilder
  • 的代碼應該使用基於JSON或使用HttpClient的形成爲基礎的方法和HttpPost或OKHttp3基於使用OKHttpClient和RequestBody。

我很快就會在此發佈工作代碼。

...這裏是工作的代碼...

import java.util.List; 
import java.util.ArrayList; 
import java.util.UUID; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpSession; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.HttpClients; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.util.EntityUtils; 
import org.json.JSONArray; 
import org.json.JSONObject; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.util.UriComponentsBuilder; 


@Controller 
public class IndexController { 

    //all oauth2 urls 
    private static final String authority = "https://login.microsoftonline.com"; 
    private static final String authorizeUrl = authority + "/common/oauth2/v2.0/authorize"; 
    private static final String tokenUrl = authority + "/common/oauth2/v2.0/token"; 
    private static final String redirectUrl = "http://localhost:8080/OutlookProfiles/authtoken"; 
    private static final String reTokenUrl = "http://localhost:8080/OutlookProfiles/showToken"; 

    //credentials 
    private static final String appId = "7414b3a3-26f1-4928-9d0b-7060d01dd41c"; 
    private static final String appPassword = "cQg9F0EaxuaErNp2YEgYaz8"; 

    private static final String[] scopes = { 
       "openid", 
       "offline_access", 
       "profile", 
       "User.Read", 
       "Contacts.Read", 
       "Mail.Read" 
       }; 


    @RequestMapping(value = "/index", method = RequestMethod.GET) 
    public String index(Model model, HttpServletRequest request, HttpServletResponse response){ 

     UUID state = UUID.randomUUID(); 
     UUID nonce = UUID.randomUUID(); 

     // Save the state and nonce in the session so we can 
     // verify after the auth process redirects back 

     HttpSession session = request.getSession(); 
     session.setAttribute("expected_state", state); 
     session.setAttribute("expected_nonce", nonce); 

     return "index"; 
    } 

    @RequestMapping(value = "/oauthorize", method = RequestMethod.POST) 
    public void oauthorize(Model model, HttpServletRequest servletRequest, HttpServletResponse servletResponse) { 

     try{ 

     UUID state = UUID.randomUUID(); 
     UUID nonce = UUID.randomUUID(); 

      HttpSession session = servletRequest.getSession(); 
      session.setAttribute("expected_state", state); 
      session.setAttribute("expected_nonce", nonce); 
      session.setAttribute("error", null); 

     UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(authorizeUrl); 
     urlBuilder.queryParam("client_id", appId); 
     urlBuilder.queryParam("redirect_uri", redirectUrl); 
     urlBuilder.queryParam("response_type", "code id_token"); 
     urlBuilder.queryParam("scope", getScopes()); 
     urlBuilder.queryParam("state", state); 
     urlBuilder.queryParam("nonce", nonce); 
     urlBuilder.queryParam("response_mode", "form_post"); 

     String locationUri = urlBuilder.toUriString(); 
     System.out.println(locationUri); 

     servletResponse.sendRedirect(locationUri); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 


    @RequestMapping(value = "/authtoken", method = RequestMethod.POST) 
    public String authorize(
       @RequestParam("code") String code, 
       @RequestParam("id_token") String idToken, 
       @RequestParam("state") UUID state, 
       HttpServletRequest servletRequest, 
       HttpServletResponse servletResponse) { 

     // Get the expected state value from the session 
     HttpSession session = servletRequest.getSession(); 
     UUID expectedState = (UUID) session.getAttribute("expected_state"); 
     UUID expectedNonce = (UUID) session.getAttribute("expected_nonce"); 


     String strState = state.toString().trim().toLowerCase(); 
     String strExState = expectedState.toString().trim().toLowerCase(); 


     // Make sure that the state query parameter returned matches 
     // the expected state 
     if (strState.equals(strExState)){ 
      session.setAttribute("authCode", code); 
      session.setAttribute("idToken", idToken); 
      System.out.println("Expectedstate : NO Error"); 
     }else { 
      session.setAttribute("error", "Unexpected state returned from authority."); 
      System.out.println("\n\nUnexpected state returned from authority."); 
     } 

     return "authtoken"; 
    } 

    @RequestMapping(value = "/getToken", method = RequestMethod.POST) 
    public void getToken(
      HttpServletRequest servletRequest, 
      HttpServletResponse servletResponse) { 

     try{ 

     HttpSession session = servletRequest.getSession(); 
     String strCode = (String) session.getAttribute("authCode"); 

     HttpClient httpClient = HttpClients.createDefault(); 
     HttpPost httpPost = new HttpPost(tokenUrl); 
     httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
      List <BasicNameValuePair> params = new ArrayList<>(); 
      params.add(new BasicNameValuePair("client_id", appId)); 
      params.add(new BasicNameValuePair("client_secret", appPassword)); 
      params.add(new BasicNameValuePair("redirect_uri", redirectUrl)); 
      params.add(new BasicNameValuePair("code", strCode)); 
      params.add(new BasicNameValuePair("grant_type", "authorization_code")); 

      httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); 
      httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 

      HttpResponse httpResponse = httpClient.execute(httpPost); 
      org.apache.http.HttpEntity entity = httpResponse.getEntity(); 
      //String theString = IOUtils.toString(entity.getContent(), "UTF-8"); 
      String strResponse = EntityUtils.toString(entity, "UTF-8"); 
      System.out.println(strResponse); 
      strResponse = "{\"response\":["+strResponse+"]}"; 
      System.out.println(strResponse); 

      JSONObject result = new JSONObject(strResponse); //Convert String to JSON Object 
      JSONArray tokenList = result.getJSONArray("response"); 
      JSONObject objJson = tokenList.getJSONObject(0); 
      String accessToken = objJson.getString("access_token"); 
      System.out.println(accessToken); 

      session.setAttribute("accessToken", accessToken); 

     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    @RequestMapping(value = "/showToken", method = RequestMethod.POST) 
    public String showToken(
      @RequestParam("token_type") String code, 
      @RequestParam("expires_in") String idToken, 
      @RequestParam("access_token") String accessToken, 
      //@RequestParam("scope") String paramScope, 
      HttpServletRequest servletRequest, 
      HttpServletResponse servletResponse) { 

     return "getToken"; 

    } 

    @RequestMapping("/logout") 
    public String logout(HttpServletRequest request) { 
     HttpSession session = request.getSession(); 
     session.invalidate(); 
     return "index"; 
    } 

    private static String getScopes() { 
      StringBuilder sb = new StringBuilder(); 
      for (String scope: scopes) { 
       sb.append(scope + " "); 
      } 

      String strscope = sb.toString().trim(); 
      System.out.println(strscope); 

      return strscope; 
    } 
}