TokiNoviceProgrammer / mrs-for-spring-boot

0 stars 0 forks source link

二要素認証周りに必要な情報 #12

Open TokiNoviceProgrammer opened 3 weeks ago

TokiNoviceProgrammer commented 3 weeks ago

AuthenticationSuccessHandlerのカスタム

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private final String redirectUrl;

    public CustomAuthenticationSuccessHandler(String redirectUrl) {
        this.redirectUrl = redirectUrl;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        response.sendRedirect(redirectUrl);
    }
}
TokiNoviceProgrammer commented 3 weeks ago

bean登録

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SecurityConfig {

    @Value("${custom.redirect.url}")
    private String redirectUrl;

    @Bean
    public AuthenticationSuccessHandler customAuthenticationSuccessHandler() {
        return new CustomAuthenticationSuccessHandler(redirectUrl);
    }
}
TokiNoviceProgrammer commented 3 weeks ago
TokiNoviceProgrammer commented 3 weeks ago

参考 https://ik.am/entries/763

TokiNoviceProgrammer commented 1 week ago

package com.example.security;

import org.springframework.security.authentication.BadCredentialsException;

public class CustomBadCredentialsException extends BadCredentialsException {

    // シリアルバージョンUIDを指定します(推奨されます)
    private static final long serialVersionUID = 1L;

    // コンストラクタを定義します
    public CustomBadCredentialsException(String msg) {
        super(msg);
    }

    public CustomBadCredentialsException(String msg, Throwable t) {
        super(msg, t);
    }

    // 独自のプロパティやメソッドを追加することもできます
}
TokiNoviceProgrammer commented 1 week ago

import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException)
            throws IOException, ServletException {
        // エラーページのパスを設定
        String errorPage = "/403";
        RequestDispatcher dispatcher = request.getRequestDispatcher(errorPage);
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        dispatcher.forward(request, response);
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAccessDeniedHandler accessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .and()
            .exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler);
    }
}

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class ErrorController {

    @GetMapping("/403")
    public String accessDenied() {
        return "403";
    }
}
TokiNoviceProgrammer commented 1 week ago

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class LoginController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private AuthenticationSuccessHandler successHandler;

    @PostMapping("/login")
    public void login(HttpServletRequest request, HttpServletResponse response) {
        try {
            String username = request.getParameter("username");
            String password = request.getParameter("password");

            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
            Authentication authentication = authenticationManager.authenticate(authRequest);

            // 認証が成功した場合、SecurityContextに設定
            SecurityContextHolder.getContext().setAuthentication(authentication);

            // 認証成功後のハンドラを実行
            successHandler.onAuthenticationSuccess(request, response, authentication);
        } catch (AuthenticationException | IOException | ServletException e) {
            // 認証が失敗した場合の処理
            e.printStackTrace();
        }
    }
}
TokiNoviceProgrammer commented 1 week ago

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class LogoutController {

    @GetMapping("/custom-logout")
    public String logout(HttpServletRequest request, HttpServletResponse response) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null){
            new SecurityContextLogoutHandler().logout(request, response, auth);
        }
        // ログアウト後にリダイレクトするページを指定します
        return "redirect:/login?logout";
    }
}