2017-09-05 1 views
0
  • Der Code scheint keinen Fehler zu haben.
  • Dies ist eine Test-App und alle IDs sind verwendbar.
  • In der Funktion getToken() kann man alternativ den Linienruf für getScopes() entsperren und weiter versuchen.
  • Ich habe eine index.jsp mit einer Taste.
  • Auf Tastendruck wird "oauthorize" aktiviert, um Code und ID_Token zu generieren.
  • Ich kann einloggen, Code und id_token werden generiert.
  • Diese Werte werden auf einer "authtoken.jsp" angezeigt, die eine Schaltfläche hat.
  • Die Schaltfläche drücken post auf /common/oauth2/v2.0/token.
  • In diesem Stadium wird 400 ungültige Anforderung auf der Microsoft-Seite angezeigt.

Ich bin nicht sicher, was falsch läuft:Outlook API für Zugriffstoken gibt 400 ungültige Anforderung in Java zurück

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; 
    } 
} 

Die 400-Fehler mit meinem Kopf ohne Grund ist in Unordnung.

+1

Ich habe keine Verwendung von Swing-in Ihrem Code sehen. Meinst du Frühling? – pcarter

+0

Danke Carter. Ich habe den Tippfehler von Swing to Spring korrigiert. –

Antwort

0
  • Microsoft Outlook API Endpunkt für Zugriffstoken: https://login.microsoftonline.com/common/oauth2/v2.0/token erwartet eine Form basiert POST d.h. Anwendung/x-www-form-urlencoded.
  • , die alle Eingabeparameter bedeutet, sollte auf Basis Form sein und nicht
  • So ist der Code technisch hängten URL
  • den Code mit UriComponentsBuilder falsch ist, sollte stattdessen verwenden JSON basierten oder basierten Ansatz bilden mit Httpclient und Httppost ODER verwenden OKHttp3 Based OKHttpClient und RequestBody.

Ich werde bald den Arbeitscode hier veröffentlichen.

... hier ist der Arbeits Code ...

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; 
    } 
} 
Verwandte Themen