부자 되기 위한 블로그, 머니킹

안녕하세요. 오늘도 열심히 개발중에 있습니다. 최근 SSO 구축에 큰 관심을 가지게 되어서 spring과 호환성이 좋은 keycloak을 열심히 연구중에 있습니다. 오늘은 회원 등록시 user 속성을 추가하는 방법과 이 값을 client 측에서 가져오는 방법에 대해서 알아보겠습니다.

 

User Attribute 추가

프로젝트 폴더의 /themes/base 폴더를 복사해주어 custom 폴더 명으로 변경합니다. theme 폴더 안에 있는 하위 폴더들은 관리 페이지에서 지정할 수 있는 theme로 잡히기 때문에 바로 base나 keycloak 폴더에서 스타일 및 폼 형식 변경을 진행해도 되지만 복사해서 만드는 것이 이전으로 복구할 때 편합니다.

 

/custom/login/register.ftl

<div class="${properties.kcFormGroupClass!} ${messagesPerField.printIfExists('phone',properties.kcFormGroupErrorClass!)}">
    <div class="${properties.kcLabelWrapperClass!}">
        <label for="user.attributes.phone" class="${properties.kcLabelClass!}">${msg("phone")}</label>
    </div>
    <div class="${properties.kcInputWrapperClass!}">
        <input
                type="text"
                id="user.attributes.phone"
                class="${properties.kcInputClass!}"
                name="user.attributes.phone"
                value="${(register.formData['user.attributes.phone']!'')}"
        />
    </div>
</div>

적당한 위치에 위와 같은 형식으로 html 파일을 붙여넣습니다.

 

이때 attribute 이름에 따라 user.attributes.[사용자 설정 속성명]으로 속성을 집언허으시면 됩니다. 저 같은 경우 phone attribute를 추가해주었습니다.

 

회원가입 페이지로 phone 입력 항목이 정상적으로 나온 모습을 확인할 수 있습니다.

 

해당 회원가입 페이지에서 새로운 회원으로 가입해줍시다.

 

가입한 user 상세보기 창 Attribute 탭에 phone 항목이 추가된 모습을 볼 수 있습니다.

 

 

 

스프링에서 User Attribute 가져오기

 

먼저 스프링에서 정상적으로 User Attribute를 가져오기 위해 관리자 페이지에서 몇가지 설정을 해줘야 합니다.

 

Client에서 Mapper에 들어가주고 create를 선택하여 Mapper를 생성합니다.

 

그리고 Clain Json Type을 String으로 설정해주어 값을 받을때 String 타입으로 받을 수 있게 합니다.

 

또 access token에 추가를 활성화 시켜 로그인시 가져오는 token을 통해 값을 받아올 수 있도록 합니다.

 

 

@GetMapping("/userinfo")
public String userInfoController(Model model) {

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();

    KeycloakPrincipal principal = (KeycloakPrincipal) auth.getPrincipal();


    KeycloakSecurityContext session = principal.getKeycloakSecurityContext();
    AccessToken accessToken = session.getToken();
    String username = accessToken.getPreferredUsername();
    String emailID = accessToken.getEmail();
    String lastname = accessToken.getFamilyName();
    String firstname = accessToken.getGivenName();
    String realmName = accessToken.getIssuer();

	// 기본 keycloak attribute
    AccessToken.Access realmAccess = accessToken.getRealmAccess();
    System.out.println("username = " + username);
    System.out.println("emailID = " + emailID);
    System.out.println("lastname = " + lastname);
    System.out.println("firstname = " + firstname);
    System.out.println("realmName = " + realmName);
    System.out.println("accessToken = " + accessToken.getSessionId());
    
   // custom user attribute
    String phone = String.valueOf(accessToken.getOtherClaims().get("phone"));
    System.out.println("phone = " + phone);

    return "page";
}

위와 같이 accessToken.getOtherClaims().get([key 값])을 통해 설정한 Custom User Attribute를 가져올 수 있습니다