> Hello World !!!

     

@syaku

Spring Security OAuth - Password 인증 방식

https://github.com/syakuis/spring-security-oauth

코드를 함께 보면서 작업하시면 도움이 됩니다.

목차


계정과 암호를 입력받아 인증 처리하는 방식이다. 일반적으로 통합 로그인에서 사용되는 인증 방식이고 제 3자에게 해당 로그인을 제공해서는 안되며, 로그인 폼은 백엔드를 통해 UI가 서빙되는 것이 보안적으로 안전할 수 있다.

작업 흐름

Spring security에서 TokenEndpoint 클래스가 Password 인증 방식을 구현한 Controller 를 제공하고 있다.

그리고 @RestController@Controller 스테레오 타입 어노테이션과 충돌을 방지하기 위해 자체적으로 @FrameworkEndpoint 를 사용한다.

주의사항은 동일한 경로의 @RequestMapping 이 정의된 경우 @FreamworkEndpoint 에 맵핑으로 정의한 경로는 무시된다.

REST API 요청에 대한 샘플은 IntelliJ Http Request 기준으로 작성하였다.

요청 예시

POST http://localhost:8080/oauth/token?grant_type=password&username=test&password=1234
Authorization: Basic ClientId ClientSecret
Content-Type: application/x-www-form-urlencoded

spring security authorization serverpassword 인증 방식은 기본적으로 /oauth/token 경로의 rest api로 구현되어있다.

경로는 AuthorizationServerEndpointsConfigurer 설정에서 변경할 수 있다.

@Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
                    .pathMapping("기존", "새로운")
        ;
    }

요청 전문

Headers

  • Authorization : Basic 인증 방식으로 값을 설정한다.요청 예시는 IntelliJ Http Request 를 사용하여 자동으로 Base64 암호화 되었다. ClientSecret은 공개되지 않도록 주의한다.
  • Basic Base64(ClientId + ClientSecret)

Parameters

  • grant_type : 인증 방식을 설정이며 password 를 설정한다.
  • username : 인증에 사용할 사용자 계정이다.
  • password : 인증에 사용할 사용자 암호이다.

응답 전문

메인 페이지의 "각 인증 방식에 대한 응답 전문"을 참고한다.

테스트 코드

@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
class PasswordRestControllerTest {
    @Autowired
    private MockMvc mvc;

    @Autowired
    private TestProperties props;

    private String username;
    private String password;
    private String clientId;
    private String clientSecret;

    @BeforeEach
    void init() {
        username = props.getUsername();
        password = props.getPassword();
        clientId = props.getClientId();
        clientSecret = props.getClientSecret();
    }

    @Test
    void accessToken() throws Exception {
        mvc.perform(post("/oauth/token")
                .param("grant_type", GrantType.PASSWORD.getValue())
                .param("username", username)
                .param("password", password)
                .with(httpBasic(clientId, clientSecret))
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .accept(MediaType.APPLICATION_JSON_VALUE)
            )
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.access_token").isNotEmpty())
            .andExpect(jsonPath("$.uid").isNotEmpty())
            .andExpect(jsonPath("$.name").isNotEmpty())
            .andDo(print())
        ;
    }
}