質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

Spring Security

Spring Securityは、Springのサブプロジェクトの一つでWebアプリケーションに必要な機能を追加します。正規ユーザーであるかを確認するための「認証機能」と、ユーザーのアクセスを制御する「認可機能」を簡単に追加することが可能です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

1回答

156閲覧

GET通信でXSRF-TOKENの取得ができない

houpuw

総合スコア2

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

Spring Security

Spring Securityは、Springのサブプロジェクトの一つでWebアプリケーションに必要な機能を追加します。正規ユーザーであるかを確認するための「認証機能」と、ユーザーのアクセスを制御する「認可機能」を簡単に追加することが可能です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2024/03/24 04:18

実現したいこと

以下のサイトを参考にしてSpring SecurityでCSRFトークンを利用するREST APIの作成を行っています。
https://volkruss.com/posts/p3398/

Angularで作成した画面からGET送信を行うとクッキーにCSRFトークンが格納されるようにしたいです。

前提

REST APIをSpringで作成し、
Angularで作成した画面(コンポーネント)からAPIの呼び出しを行っています。

発生している問題・エラーメッセージ

PostmanからGET送信をするとクッキーにCSRFトークンが設定されていることが確認できるのですが、
Angularで作成した画面のボタンからGET送信をしてもクッキーにCSRFトークンが設定されません。
Postmanでは正常にCSRFトークンが取得できていることからAngular側で何か設定が必要なのではないかと考えてます。
原因と対処法がありましたらご教示いただきたいです。

・PostmanでGET送信
イメージ説明

・Angularで作成した画面からGET通信してもクッキーにCSRFトークンが設定されない
イメージ説明

<補足>
GET通信ではCSRFトークンが設定されませんが、
POST通信を行うとCSRFトークンが設定されます。
イメージ説明

そのため、参考サイトではGET通信→POST通信で403エラーが発生せずに通信ができていますが、
私の環境ではGET通信→POST通信(403エラー)→POST通信(200)となります。

該当のソースコード

SecurityConfig.java

1import java.util.Arrays; 2 3import org.springframework.context.annotation.Bean; 4import org.springframework.context.annotation.Configuration; 5import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7import org.springframework.security.web.SecurityFilterChain; 8import org.springframework.security.web.csrf.CookieCsrfTokenRepository; 9import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler; 10import org.springframework.web.cors.CorsConfiguration; 11import org.springframework.web.cors.CorsConfigurationSource; 12import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 13 14@Configuration 15@EnableWebSecurity 16public class SecurityConfig { 17 @Bean 18 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 19 20 http.cors(cors -> cors.configurationSource(corsConfigurationSource())); 21 22 http.csrf((csrf) -> csrf 23 .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 24 .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler())); 25 26 http.authorizeHttpRequests(authorize -> { 27 authorize.requestMatchers("/**").permitAll(); 28 }); 29 30 return http.build(); 31 } 32 33 //CORSの設定 34 @Bean 35 public CorsConfigurationSource corsConfigurationSource() { 36 CorsConfiguration cors = new CorsConfiguration(); 37 cors.setAllowedOrigins(Arrays.asList("http://localhost:4200")); 38 cors.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS")); 39 cors.setAllowedHeaders(Arrays.asList("*")); 40 cors.setAllowCredentials(true); 41 cors.addExposedHeader("X-AUTH-TOKEN"); 42 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 43 source.registerCorsConfiguration("/**",cors); 44 return source; 45 } 46}

testController.java

1import org.springframework.security.core.Authentication; 2import org.springframework.security.core.context.SecurityContextHolder; 3import org.springframework.web.bind.annotation.GetMapping; 4import org.springframework.web.bind.annotation.PostMapping; 5import org.springframework.web.bind.annotation.RestController; 6 7@RestController 8public class testController { 9 10 @GetMapping("/get") 11 public String doGet() { 12 System.out.println("GET"); 13 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 14 System.out.println(authentication); 15 return "sample GET is done"; 16 } 17 18 @PostMapping("/post") 19 public String doPost() { 20 System.out.println("POST"); 21 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 22 System.out.println(authentication); 23 return "sample POST is done"; 24 } 25 26} 27

html

1 <button id="get" (click)="doget()">GET</button> 2 <button id="post" (click)="dopost()">POST</button> 3 ...

component.ts

1import { Component } from '@angular/core'; 2import { DashboardService } from './dashboard.service' 3import { HttpClientModule } from '@angular/common/http'; 4 5@Component({ 6 selector: 'app-dashboard', 7 standalone: true, 8 imports: [HttpClientModule], 9 templateUrl: './dashboard.component.html', 10 styleUrl: './dashboard.component.css' 11}) 12export class DashboardComponent { 13 message: string; 14 15 constructor(private dashboardService: DashboardService,) { 16 this.message = 'This is a sample of Angular application.'; 17 } 18 19doget(){ 20 21 fetch('http://localhost:8080/get', 22 { 23 method:'GET', 24 credentials: 'include' 25 }) 26 .then(res => res.text()) 27 .then(str =>console.log(str)) 28} 29 30 31dopost(){ 32 const csrfToken = document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s*\=\s*([^;]*).*$)|^.*$/, '$1'); 33 console.log(csrfToken); 34 fetch('http://localhost:8080/post',{ 35 method:'POST', 36 credentials: 'include', 37 headers: { 38 'X-XSRF-TOKEN' : csrfToken 39 }, 40 }) 41 .then(res => res.text()) 42 .then(str => console.log(str)) 43} 44}~~打ち消し線~~

補足情報(FW/ツールのバージョンなど)

spring-boot-starter-parent:3.2.4
Spring Security Version: 6.2.3
Eclipse IDE for Java Developers Version: 2023-12 (4.30.0)
Postman for Windows:10.24.7

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

GET通信でCSRFトークンを発行するには、トークンをメソッドの引数・戻り値に指定してやる必要があるようでした。

以下のサイトを参考にしました。
https://qiita.com/d-yosh/items/c76938057a634eed0d6f
・CSRF トークンを返却するエンドポイントを公開する

<修正前>

testController.java

1 @GetMapping("/get") 2 public String doGet() { 3 return "sample GET is done"; 4 }

<修正後>

testController.java

1 @GetMapping("/get") 2 public CsrfToken doGet(CsrfToken token) { 3 return token; 4 }

投稿2024/03/24 13:05

houpuw

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問