Skip to content

Instantly share code, notes, and snippets.

@kjunichi
Last active March 8, 2023 07:09
Show Gist options
  • Save kjunichi/03a1f508479dd38dbd7f4cd19d6c4e3f to your computer and use it in GitHub Desktop.
Save kjunichi/03a1f508479dd38dbd7f4cd19d6c4e3f to your computer and use it in GitHub Desktop.

JSONベースでの認証APIを作成

以下のクラスを継承した

  • UsernamePasswordAuthenticationFilter
  • AuthenticationProvider
  • UserDetails 要らないかも

curlコマンドの操作

JSONをPOSTする

curl -H "Content-Type: application/json" -d "{\"username\" : \"user2\" , \"password\" : \"sato@example.com\"}" localhost:8080/api/login -v
@kjunichi
Copy link
Author

kjunichi commented Mar 8, 2023

package com.example.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    ObjectMapper objectMapper = new ObjectMapper();
    String usernameParameter = "username";
    String passwordParameter = "password";
    private final AuthenticationManager authenticationManager;
    public JsonUsernamePasswordAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/api/login", "POST"));
        // 成功した場合の処理, 今回は取得した person 情報を返しています。
        this.setAuthenticationSuccessHandler((req, res, ex) -> {
            res.setStatus(200);
            String username = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            res.getWriter().write((new ObjectMapper()).writeValueAsString(username));
        });
        this.logger.info("hogehoge");
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> requestObject;
        try {
            requestObject = objectMapper.readValue(request.getInputStream(), Map.class);
        } catch (IOException e) {
            requestObject = new HashMap<>();
        }

        String username =
                Optional
                        .ofNullable(requestObject.get(usernameParameter))
                        .map(Object::toString)
                        .map(String::trim)
                        .orElse("");
        String password =
                Optional
                        .ofNullable(requestObject.get(passwordParameter))
                        .map(Object::toString)
                        .orElse("");

        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(
                username, password);

        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

        return this.authenticationManager.authenticate(authRequest);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment