web-dev-qa-db-fra.com

ng2 obtenir le jeton de csrf du cookie l'afficher comme en-tête

Après avoir passé deux jours complets à chercher sur le Web et à lire des docs et des tonnes de questions en suspens concernant des personnes confrontées au même problème, je ne comprends toujours pas comment Angular 2 traite les cookies (x-Origin) et comment y accéder. 

Le problème: Le serveur back-end envoie 2 cookies avec x-csrf-token & JSESSIONID à l'intérieur. Mon travail consiste à conserver le jeton csrf en mémoire (ng2) et à le renvoyer (uniquement) en tant que en-tête (sans cookie) avec chaque message envoyé au serveur dorsal.

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Set-Cookie: x-csrf-token=8555257a-396f-43ac-8587-c6d489e76026; Path=/app
Set-Cookie: JSESSIONID=73E38392C60370E38FBAF80143ECE212; Path=/app/; HttpOnly
Expires: Thu, 12 Apr 2018 07:49:02 GMT
Cache-Control: max-age=31536000
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 12 Apr 2017 07:49:02 GMT

Ma solution partielle: J'ai créé une classe RequesstOptions personnalisée qui étend BaseRequestOptions. Ajout d’en-têtes supplémentaires et définition du paramètre 'withCredentials'.

export class MyRequestOptions extends BaseRequestOptions {

  headers: Headers = new Headers({
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  });

  withCredentials = true;
}

Dans mon HttpService je fais le post et je me fais comme ça:

@Injectable()
export class HttpService {

  constructor(
    protected _http: Http,
    protected requestOptions: RequestOptions
  ) {  }

  get(url): Observable<any> {
    return this._http.get(url, this.requestOptions).map( res => res.json() );
  }

  post(url: string, object: any): Observable<any> {
    return this._http.post(url, object, this.requestOptions).map( res => res.json() );
  }
}

et dans mon app.module je fais la magie comme suit:

 providers: [
    { provide: RequestOptions, useClass: DocumentumDefaultRequestOptions },
    { provide: XSRFStrategy, useFactory: xsrfFactory }
  ],

mon xsrfFactory

export function xsrfFactory() {
  return new CookieXSRFStrategy('x-csrf-token', 'x-csrf-token');
}

Mon résultat partiel: À ce stade, Angular envoie un cookie à chaque requête (GET et POST sans discrimination) avec les attributs jsessionid et x-csrf-token, comme suit:

POST /app/business-objects/business-objects-type HTTP/1.1
Host: localhost:8040
Connection: keep-alive
Content-Length: 26
Pragma: no-cache
Cache-Control: no-cache
Authorization: Basic ZG1hZG1pbjphZG1pbg==
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Content-Type: application/json
Accept: application/json
Referer: http://localhost:4200/page
Cookie: JSESSIONID=B874C9A170EFC12BEB0EDD4266896F2A; x-csrf-token=0717876e-f402-4a1c-a31a-2d60e48509d3

Mes questions d'un milliard de dollars:

  • Comment et où puis-je accéder au jeton x-csrf et comment puis-je l'ajouter à mes demandes?
  • Que fait exactement CookieXSRFStrategy('x-csrf-token', 'x-csrf-token');? Je n'aime pas la sensation de boîte noire/comprend la façon dont les docs l'ont expliqué. Puis-je y accéder pour des données?

Avant d'envoyer une demande HTTP, CookieXSRFStrategy recherche un cookie appelé XSRF-TOKEN et définit un en-tête nommé X-XSRF-TOKEN avec la valeur de ce cookie.

  • Cela ne définit pas l'en-tête dans mon cas ... mais pourquoi?

  • En ce moment, j'envoie le cookie au serveur avec les identifiants sessionid et csrf, mais que envoie-t-il? L'indicateur CookieXSRFStrategy ou 'withCredentials'.

Merci de ne pas répondre avec un seul type de document comme "document.cookie". Les données sont inutiles sans leurs métadonnées

7
VikingCode

Angular a un support intégré pour XSRF voir ici: https://angular.io/guide/http#security-xsrf-protection

"Lors de l'exécution de requêtes HTTP, un intercepteur lit un jeton dans un cookie, par défaut, XSRF-TOKEN, et le définit comme un en-tête HTTP, X-XSRF-TOKEN"

Donc, si votre serveur définit un cookie nommé XSRF-TOKEN, alors il fonctionnera automatiquement! Rien à faire côté client . Si vous souhaitez nommer votre cookie/en-tête de quelque manière que ce soit, vous pouvez le faire. ainsi que:

imports: [
  HttpClientModule,
  HttpClientXsrfModule.withConfig({
    cookieName: 'My-Xsrf-Cookie',
    headerName: 'My-Xsrf-Header',
  }),
]

ET si vous utilisez la sécurité de printemps, il prend en charge les conventions de dénomination angulaire afin que vous puissiez configurer ce côté serveur:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeRequests()
            ....    
0
MarkJ