2016-12-29 1 views
1

Je tente d'authentifier Microsoft OneDrive, avec le service REST, dans mon application, en utilisant Java pour backend et Ionic 2. L'authentification fonctionne maintenant si j'appelle mon service directement depuis Chrome . je poste le code:Authentification Services Microsoft OneDrive REST Java/Ionic 2

private static final String REDIRECT_URI = "http://localhost:8080/CloudToCloud/onedrive/getToken"; 

@RequestMapping(value = { "/getAccess" }, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public void authorizationFlow(HttpServletRequest request, HttpServletResponse response) 
     throws IOException, InterruptedException { 
    try { 
     String authURL = "https://login.live.com/oauth20_authorize.srf?client_id=" + CLIENT_ID 
       + "&scope=wl.signin%20wl.basic%20wl.offline_access%20wl.skydrive_update&response_type=code&redirect_uri=" 
       + REDIRECT_URI; 
     response.sendRedirect(authURL); 
    } catch (Exception e) { 
     logger.severe(e.getMessage()); 
    } 
} 

@RequestMapping(value = { "/getToken" }, params = { "code" }, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
public ResponseEntity<JSONObject> getToken(@RequestParam("code") String code) 
     throws IOException, InterruptedException, ParseException { 
    JSONObject json = null; 
    try { 
     logger.info("Auth CODE: " + code); 
     String url = "https://login.live.com/oauth20_token.srf"; 
     URL obj = new URL(url); 
     HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); 

     con.setRequestMethod("POST"); 
     con.setRequestProperty("User-Agent", "Mozilla/5.0"); 
     con.setRequestProperty("Accept-Language", "en-US,en;q=0.5"); 

     String urlParameters = "client_id=" + CLIENT_ID + "&" + "redirect_uri=" + REDIRECT_URI + "&" 
       + "client_secret=" + SECRET + "&" + "code=" + code + "&" + "grant_type=authorization_code"; 
     logger.info(url + urlParameters); 

     con.setDoOutput(true); 
     DataOutputStream wr = new DataOutputStream(con.getOutputStream()); 
     wr.writeBytes(urlParameters); 
     wr.flush(); 
     wr.close(); 

     int responseCode = con.getResponseCode(); 
     logger.info("REQUEST SENT. Response Code : " + responseCode); 

     BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     String risposta = response.toString(); 
     JSONParser parser = new JSONParser(); 
     json = (JSONObject) parser.parse(risposta); 
     String token = json.get("access_token").toString(); 

     FileWriter file = new FileWriter(DATA_STORE_DIR); 
     file.write(json.toJSONString()); 

     logger.info("\nTOKEN:\n" + token); 

     file.flush(); 
     file.close(); 
     return new ResponseEntity<JSONObject>(json, HttpStatus.OK); 
    } catch (Exception e) { 
     logger.info("ERRORE: " + e.getMessage()); 
     return new ResponseEntity<JSONObject>(HttpStatus.BAD_REQUEST); 
    } 
} 

J'appelle le premier service, je reçois un code, et je fais un redirect sur le deuxième service, ce qui me donne un JSON avec le jeton, à utiliser pour tous les autres appels . Jusqu'à ce que tout fonctionne. Le problème vient à l'aide ionique 2. Je posterai le code:

Le service:

getAuthOneDrive(){ 
    var url = 'http://localhost:8080/CloudToCloud/onedrive/getAccess'; 
    var response = this.http.get(url).map(res => res.json()); 
    return response; 
} 

Le composant:

getAuthOneDrive(){ 
    this.cloudServiceAuthentication.getAuthOneDrive().subscribe(
    err => { 
     console.log(err); 
    }, 
    () => console.log('getAuthOneDrive Complete') 
); 
} 

Et ma procuration, que j'ai configuré en ionic.config .json:

{ 
    "name": "C2C", 
    "app_id": "c6203dd8", 
    "v2": true, 
    "typescript": true, 
    "proxies": [ 
    { 
     "path": "/", 
     "proxyUrl": "http://localhost:8080/" 
    } 
    ] 
} 

Si je tente d'appeler le même service (http://localhost:8080/CloudToCloud/onedrive/getAcces), de l'application dans Ionic2, par un clic sur un bouton, j'obtiens cette erreur.

XMLHttpRequest cannot load http://localhost:8080/CloudToCloud/onedrive/getAccess. Redirect from 'http://localhost:8080/CloudToCloud/onedrive/getAccess' to 'https://login.live.com/oauth20_authorize.srf?client_id=ae9573ba-6bc0-4a87-8…ype=code&redirect_uri=http://localhost:8080/CloudToCloud/onedrive/getToken' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. 

J'ai vraiment tout essayé. Si quelqu'un peut me donner un coup de main, je serais reconnaissant. Merci! ;)

EDIT:

C'est ce que j'ai essayé de faire: 1- ajouter « Access-Control-Allow-Origin ', '*' en-tête, j'ai cette erreur:

XMLHttpRequest cannot load http://localhost:8080/CloudToCloud/onedrive/getAccess. Redirect from 'http://localhost:8080/CloudToCloud/onedrive/getAccess' to 'https://login.live.com/oauth20_authorize.srf?client_id=ae9573ba-6bc0-4a87-8…ype=code&redirect_uri=http://localhost:8080/CloudToCloud/onedrive/getToken' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect. 

2- ne pas utiliser response.sendRedirect dans le premier service, mais répondre à la demande avec HttpsURLConnection ou au printemps RestTemplate, 3- essayez d'appeler le service Microsoft directement à partir ionique, 4- utiliser l'annotation Spring @ CrossOrigin, mais j'ai la même erreur

Répondre

0

J'ai résolu en modifiant le premier service/getAccess, en ajoutant l'en-tête Access-Control-Allow-Origin et en utilisant mon REDIRECT_URI et non plus le sendRedirect qui a donné des problèmes.

@CrossOrigin(origins = "*") 
@RequestMapping(value = { "/getAccess" }, method = RequestMethod.GET) 
public void authenticate() throws IOException { 
    try { 
     OneDriveSDK sdk = OneDriveFactory.createOneDriveSDK(CLIENT_ID, SECRET, REDIRECT_URI, 
       OneDriveScope.READWRITE); 
     String url = sdk.getAuthenticationURL(); 
     logger.info(url); 
     openWebpage(url); 
     URL obj = new URL(url); 
     HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); 
     con.setRequestMethod("GET"); 
     con.setRequestProperty("Access-Control-Allow-Origin", "*"); 
     con.setDoOutput(true); 
     int responseCode = con.getResponseCode(); 
     logger.info("REQUEST SENT. Response Code : " + responseCode); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
0

Les demandes d'origine croisée sont limitées par le navigateur pour des raisons de sécurité. Jetez un oeil à HTTP access control (CORS) pour une explication détaillée de la façon dont cela fonctionne.

Réglage de l'en-tête suivant devrait vous permettre de travailler autour de la question dans le développement:

Access-Control-Allow-Origin: * 

Assurez-vous d'enlever cette tête (ou au moins limiter au-delà de « * ») dans votre déploiement de production.

+0

Si j'ajoute cet en-tête, qui avait déjà essayé de le faire, je reçois cette erreur: « XMLHttpRequest ne peut pas charger https://login.live.com/oauth20_authorize.srf?client_id=ae9573ba-6bc0-4a87- 8 ... ype = code & redirect_uri = http: // localhost: 8080/CloudToCloud/onedrive/getToken Aucun en-tête 'Access-Control-Allow-Origin' n'est présent sur la ressource demandée L'origine 'null' n'est donc pas autorisée. " Je pense que la raison est que le service Microsoft n'accepte pas cet en-tête. –