0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Spring Security入門

Posted at

Spring Security入門

はじめに

Spring Securityは、Spring Frameworkベースのアプリケーションに認証・認可の機能を提供するフレームワークです。この記事では、Spring Securityの基本的な設定と使用方法について解説します。

基本的な設定

1. 依存関係の追加

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. 基本的なセキュリティ設定

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .defaultSuccessUrl("/dashboard")
                .permitAll()
            )
            .logout(logout -> logout
                .logoutSuccessUrl("/login?logout")
                .permitAll()
            );
            
        return http.build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

認証の実装

1. ユーザーサービスの実装

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("ユーザーが見つかりません: " + username));
            
        return org.springframework.security.core.userdetails.User
            .withUsername(user.getUsername())
            .password(user.getPassword())
            .roles(user.getRoles().toArray(new String[0]))
            .build();
    }
}

2. ユーザーエンティティの定義

@Entity
@Table(name = "users")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true)
    private String username;
    
    private String password;
    
    @ElementCollection(fetch = FetchType.EAGER)
    private Set<String> roles = new HashSet<>();
    
    // getters and setters
}

認可の実装

1. メソッドレベルのセキュリティ

@Service
public class UserService {
    
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteUser(Long userId) {
        // ユーザー削除処理
    }
    
    @PreAuthorize("hasRole('USER')")
    public User getCurrentUser() {
        // 現在のユーザー情報取得
    }
}

2. コントローラーレベルのセキュリティ

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @GetMapping("/profile")
    @PreAuthorize("isAuthenticated()")
    public UserProfile getProfile() {
        // プロフィール情報の取得
    }
    
    @PostMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public void adminOperation() {
        // 管理者操作
    }
}

セキュリティの基本機能

1. パスワードエンコーディング

@Service
public class UserRegistrationService {
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    public void registerUser(UserRegistrationDto dto) {
        User user = new User();
        user.setUsername(dto.getUsername());
        user.setPassword(passwordEncoder.encode(dto.getPassword()));
        user.setRoles(Collections.singleton("USER"));
        userRepository.save(user);
    }
}

2. CSRF保護

@Configuration
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf
                .ignoringRequestMatchers("/api/**")  // APIエンドポイントではCSRF保護を無効化
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
            );
        return http.build();
    }
}

セキュリティのベストプラクティス

  1. パスワードの取り扱い

    • 強力なパスワードエンコーダーの使用
    • パスワードのハッシュ化
    • ソルトの使用
  2. セッション管理

    • セッションタイムアウトの設定
    • 同時ログインの制御
    • セッション固定攻撃への対策
  3. エラーハンドリング

    • 適切なエラーメッセージ
    • ログイン失敗の制限
    • アカウントロックアウト
  4. セキュリティヘッダー

    • XSS対策
    • クリックジャッキング対策
    • HSTSの設定

実装例:ログインフォーム

<form th:action="@{/login}" method="post">
    <div>
        <label>ユーザー名:</label>
        <input type="text" name="username" required/>
    </div>
    <div>
        <label>パスワード:</label>
        <input type="password" name="password" required/>
    </div>
    <div>
        <input type="submit" value="ログイン"/>
    </div>
</form>

まとめ

Spring Securityは、アプリケーションに強力なセキュリティ機能を提供します。適切な設定と実装により、安全なアプリケーションを構築することができます。

参考資料

  • Spring Security公式ドキュメント
  • OWASPセキュリティガイドライン
  • Spring Boot Reference Guide
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?