다음을 통해 공유


Spring 웹앱에 Azure Active Directory B2C로 로그인 추가

이 문서에서는 Microsoft Entra ID용 Spring Boot Starter와 함께 Spring Initializr 사용하여 로그인 기능이 있는 Java 앱을 만드는 방법을 보여줍니다.

이 자습서에서는 다음 방법을 알아봅니다.

  • Spring Initializr를 사용하여 Java 애플리케이션 만들기
  • Azure Active Directory B2C 구성
  • Spring Boot 클래스 및 주석을 사용하여 애플리케이션 보호
  • Java 애플리케이션 빌드 및 테스트

Microsoft Entra ID Microsoft의 클라우드 규모 엔터프라이즈 ID 솔루션입니다. Azure Active Directory B2C Microsoft Entra ID의 기능 집합을 보완하여 B2C(기업-소비자) 애플리케이션에 대한 고객, 소비자 및 시민 액세스를 관리할 수 있습니다.

필수 구성 요소

  • Azure 구독. 아직 계정이 없다면 시작하기 전에 무료 계정 만드십시오.
  • 지원되는 JDK(Java Development Kit)입니다. Azure에서 개발할 때 사용할 수 있는 JDK에 대한 자세한 내용은 Azure 및 Azure StackJava 지원을 참조하세요.
  • Apache Maven버전 3.0 이상.

중요하다

이 문서의 단계를 완료하려면 Spring Boot 버전 2.5 이상이 필요합니다.

Spring Initializr를 사용하여 앱 만들기

  1. https://start.spring.io/로 이동합니다.

  2. 이 지침에 따라 값을 입력합니다. 레이블 및 레이아웃은 여기에 표시된 이미지와 다를 수 있습니다.

    • 프로젝트에서 Maven 프로젝트을 선택합니다.
    • 언어에서 Java을 선택합니다.
    • Spring Boot아래에서 2.7.11선택합니다.
    • 그룹, 아티팩트, 및 이름 에 같은 값을 입력하십시오. 이때 간단한 설명 문자열을 사용하세요. UI는 입력할 때 이러한 필드 중 일부를 자동으로 채울 수 있습니다.
    • 종속성 창에서 종속성 추가를 선택합니다. UI를 사용하여 Spring WebSpring Security종속성을 추가합니다.

    메모

    Spring Security 5.5.1, 5.4.7, 5.3.10 및 5.2.11은 CVE-2021-22119에 다음 CVE 보고서를 해결하기 위해 릴리스되었습니다. spring-security-oauth2-client사용한 서비스 거부 공격. 이전 버전을 사용하는 경우 업그레이드하세요.

  3. 프로젝트 생성을 선택한 다음, 로컬 컴퓨터의 경로에 프로젝트를 다운로드합니다. 다운로드한 파일을 프로젝트의 이름을 딴 디렉터리로 이동하고 파일의 압축을 풉 파일 레이아웃은 그룹에 대해 입력한 값이 yourProject를 대체하며 다음과 같이 보일 것입니다.

    .
    ├── HELP.md
    ├── mvnw
    ├── mvnw.cmd
    ├── pom.xml
    └── src
        ├── main
        │   ├── java
        │   │   └── yourProject
        │   │       └── yourProject
        │   │           └── YourProjectApplication.java
        │   └── resources
        │       ├── application.properties
        │       ├── static
        │       └── templates
        └── test
            └── java
                └── yourProject
                    └── yourProject
                        └── YourProjectApplicationTests.java
    

Microsoft Entra 인스턴스 만들기 및 초기화

Active Directory 인스턴스 만들기

  1. https://portal.azure.com에 로그인하세요.

  2. 리소스 만들기을 선택합니다. Azure Active Directory B2C검색하기.

    Azure Portal을 사용하여 새 Azure Active Directory B2C 인스턴스를 만듭니다.

  3. 선택합니다.만들기.

    Azure Marketplace의 Azure Active Directory B2C 항목 .

  4. 을 선택하여 새 Azure AD B2C 테넌트을 만듭니다.

    Azure 포털 옵션으로 새로운 Azure AD B2C 테넌트를 만듭니다.

  5. 조직 이름초기 도메인 이름에 적절한 값을 입력한 후, 만들기를 선택합니다.

    Azure AD B2C 테넌트를 생성하는 화면입니다

  6. Active Directory 만들기가 완료되면 오른쪽 위 모서리에서 계정을 선택하고 디렉터리 전환버튼을 선택한 다음, 만든 디렉터리를 선택합니다. 새 테넌트 홈 페이지로 리디렉션됩니다. 그런 다음, 검색하고 Azure AD B2C선택합니다.

    Azure AD B2C 서비스를 찾습니다.

Spring Boot 앱에 대한 애플리케이션 등록 추가

  1. 관리 창에서 앱 등록을(를) 선택하고, 새 등록을(를) 선택합니다.

    Azure AD B2C 앱 등록 화면을 보여 주는 Azure Portal의 스크린샷

  2. 이름 필드에 앱의 이름을 입력한 다음 등록을 선택합니다.

    Azure AD B2C는 애플리케이션 양식을 등록합니다.

  3. 관리 패널로 돌아가서 앱 등록을 선택한 다음, 만든 애플리케이션 이름을 선택합니다.

    표시 이름이 선택된 앱 등록 화면입니다.

  4. 인증을 선택한 다음, 플랫폼 추가, 그 다음에 . 리디렉션 URI 설정한 다음,구성 선택합니다.

    인증을 위해 선택한 옵션, 플랫폼, 웹을 추가합니다.

    리디렉션 URI 필드가 선택된 웹 화면 구성

앱에 특정 비밀을 추가하십시오

인증서 & 비밀을 선택한 다음 새 클라이언트 비밀. 비밀 설명을 입력한 다음 추가를 선택합니다. 비밀을 만든 후 비밀 값 옆에 있는 복사 아이콘을 선택하여 이 문서의 뒷부분에서 사용할 값을 복사합니다.

클라이언트 비밀 화면을 추가합니다.

복사 단추가 선택된 인증서 및 비밀 화면

메모

인증서 & 비밀 섹션을 나갔다가 돌아오면, 비밀 값을 볼 수 없게 됩니다. 이 경우 나중에 사용할 수 있도록 다른 비밀을 만들고 복사해야 합니다. 때때로 생성된 비밀 값에는 백슬래시 또는 백틱과 같은 application.yml 파일에 포함할 때 문제가 되는 문자가 포함될 수 있습니다. 이 경우 해당 비밀을 삭제하고 다른 비밀을 생성합니다.

사용자 흐름 추가

  1. 테넌트 메인 페이지로 이동하세요. 왼쪽 창의 정책 섹션에서 사용자 흐름선택한 다음, 새 사용자 흐름선택합니다.

  2. 이제 이 자습서를 떠나 다른 자습서를 실행하고 완료되면 이 자습서로 돌아갑니다. 다른 자습서로 이동하면 다음과 같은 사항에 유의해야 합니다.

    • 새 사용자 흐름을 선택하도록 요청하는 단계로 시작합니다.
    • 이 자습서에서 webapp1을 참조할 때, 대신 그룹에 입력한 값을 사용하십시오.
    • 흐름에서 반환할 클레임을 선택할 때, 표시 이름을 선택했는지 확인하세요. 이 클레임이 없으면 이 자습서에서 빌드되는 앱이 작동하지 않습니다.
    • 사용자 흐름을 실행하라는 메시지가 표시되면 이전에 지정한 리디렉션 URL이 아직 활성화되지 않았습니다. 흐름을 계속 실행할 수 있지만 리디렉션이 성공적으로 완료되지 않습니다. 예상된 일입니다.
    • "다음 단계"에 도달하면 이 자습서로 돌아갑니다.

    자습서의 모든 단계를 수행합니다. Azure Active Directory B2C 사용자 흐름을 만들어 "등록 및 로그인", "프로필 편집" 및 "암호 재설정"에 대한 사용자 흐름을 만듭니다.

    Azure AD B2C는 로컬 계정과 소셜 ID 공급자를 지원합니다. GitHub ID 공급자를 만드는 예제는 Azure Active Directory B2C사용하여 GitHub 계정으로 등록 설정 및 로그인을 참조하세요.

앱 구성 및 컴파일

이제 Azure AD B2C 인스턴스 및 일부 사용자 흐름을 만들었으므로 Spring 앱을 Azure AD B2C 인스턴스에 연결합니다.

  1. 명령줄에서 Spring Initializr에서 다운로드한 .zip 파일의 압축을 푼 디렉터리로 이동하기 위해 'cd' 명령어를 사용하세요.

  2. 프로젝트의 부모 폴더로 이동하고 텍스트 편집기에서 pom.xml Maven 프로젝트 파일을 엽니다.

  3. Spring OAuth2 보안을 위해 pom.xml에 종속성을 추가합니다.

    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-active-directory-b2c</artifactId>
        <version>See Below</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
        <version>See Below</version>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        <version>See Below</version>
    </dependency>
    

    spring-cloud-azure-starter-active-directory-b2c에 대해 사용 가능한 최신 버전을 사용하세요. mvnrepository.com을 사용하여 조회할 수 있으실 수 있습니다.

    spring-boot-starter-thymeleaf경우 위에서 선택한 Spring Boot 버전에 해당하는 버전(예: 2.3.4.RELEASE)을 사용합니다.

    thymeleaf-extras-springsecurity5경우 사용 가능한 최신 버전을 사용합니다. mvnrepository.com을(를) 사용하여 조회할 수 있을 수도 있습니다. 이 글을 쓰는 시점에서 최신 버전은 3.0.4.RELEASE.

  4. pom.xml 파일을 저장하고 닫습니다.

    • mvn -DskipTests clean install실행하여 종속성이 올바른지 확인합니다. BUILD SUCCESS표시되지 않으면 계속하기 전에 문제를 찾아내 해결하세요.
  5. 프로젝트의 src/main/resources 폴더로 이동하고 텍스트 편집기에서 application.yml 파일을 만듭니다.

  6. 이전에 만든 값을 사용하여 앱 등록에 대한 설정을 지정합니다. 예를 들어:

    spring:
      cloud:
        azure:
          active-directory:
            b2c:
              enabled: true
              base-uri: https://<your-tenant-initial-domain-name>.b2clogin.com/<your-tenant-initial-domain-name>.onmicrosoft.com/
              credential:
                client-id: <your-application-ID>
                client-secret: '<secret-value>'
              login-flow: sign-up-or-sign-in
              logout-success-url: <your-logout-success-URL>
              user-flows:
                sign-up-or-sign-in: <your-sign-up-or-sign-in-user-flow-name> 
                profile-edit: <your-profile-edit-user-flow-name> 
                password-reset: <your-password-reset-user-flow-name> 
              user-name-attribute-name: <your-user-name-attribute-name> 
    

    client-secret 값은 작은따옴표로 묶여 있습니다. <secret-value> 값은 YAML에 있을 때 작은따옴표 안에 있어야 하는 일부 문자를 거의 확실하게 포함하기 때문에 필요합니다.

    메모

    이 문서 작성을 기준으로 application.yml 사용할 수 있는 Active Directory B2C Spring Integration 값의 전체 목록은 다음과 같습니다.

    spring:
      cloud:
        azure:
          active-directory:
            b2c:
              enabled: true
              base-uri:
              credential:
                client-id:
                client-secret:
              login-flow:  
              logout-success-url:
              user-flows:
                sign-up-or-sign-in:
                profile-edit: # optional
                password-reset: # optional
              user-name-attribute-name:
    

    application.yml 파일은 GitHub의 spring-cloud-azure-starter-active-directory-b2c 샘플 aad-b2c-web-application에서 제공됩니다.

  7. application.yml 파일을 저장하고 닫습니다.

  8. 그룹입력한 값으로 바꿔서 src/main/java/src/main/java/컨트롤러라는 폴더를 만듭니다.

  9. 컨트롤러 폴더에 WebController.java이라는 새 Java 파일을 만들고 텍스트 편집기에서 엽니다.

  10. 다음 코드를 입력하고 yourGroupId 적절하게 변경한 다음 파일을 저장하고 닫습니다.

    package yourGroupId.yourGroupId.controller;
    
    import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
    import org.springframework.security.oauth2.core.user.OAuth2User;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class WebController {
    
        private void initializeModel(Model model, OAuth2AuthenticationToken token) {
            if (token != null) {
                final OAuth2User user = token.getPrincipal();
    
                model.addAttribute("grant_type", user.getAuthorities());
                model.addAllAttributes(user.getAttributes());
            }
        }
    
        @GetMapping(value = "/")
        public String index(Model model, OAuth2AuthenticationToken token) {
            initializeModel(model, token);
    
            return "home";
        }
    
        @GetMapping(value = "/greeting")
        public String greeting(Model model, OAuth2AuthenticationToken token) {
            initializeModel(model, token);
    
            return "greeting";
        }
    
        @GetMapping(value = "/home")
        public String home(Model model, OAuth2AuthenticationToken token) {
            initializeModel(model, token);
    
            return "home";
        }
    }
    

    컨트롤러의 모든 메서드가 호출하고 해당 메서드가 호출하기 때문에 src/main/resources/templates의 모든 HTML 페이지는 , 또는 같은 특성에 액세스할 수 있습니다. user.getAttributes()에서 반환된 값은 사실 인증을 위한 id_token의 클레임입니다. 사용 가능한 클레임의 전체 목록은 Microsoft ID 플랫폼 ID 토큰에 제공됩니다.

  11. src/main/java/<yourGroupId>/<yourGroupId>경로에 "security" 이름의 폴더를 생성하고, yourGroupId을(를) 그룹에 입력한 값으로 대체하세요.

  12. 보안 폴더에 WebSecurityConfiguration.java이라는 새 Java 파일을 만들고 텍스트 편집기에서 엽니다.

  13. 다음 코드를 입력하고 yourGroupId 적절하게 변경한 다음 파일을 저장하고 닫습니다.

    package yourGroupId.yourGroupId.security;
    
    import com.azure.spring.cloud.autoconfigure.aadb2c.AadB2cOidcLoginConfigurer;
    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;
    
    @EnableWebSecurity
    public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    
        private final AadB2cOidcLoginConfigurer configurer;
    
        public WebSecurityConfiguration(AadB2cOidcLoginConfigurer configurer) {
            this.configurer = configurer;
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .apply(configurer)
            ;
        }
    }
    
  14. home.html 파일을 spring-cloud-azure-starter-active-directory-b2c 샘플의 aad-b2c-web-application에서 src/main/resources/templates로 복사하고, ${your-profile-edit-user-flow}${your-password-reset-user-flow}을 앞에서 만든 사용자 흐름의 이름으로 바꿉니다.

앱 빌드 및 테스트

  1. 명령 프롬프트를 열고 디렉터리를 앱의 pom.xml 파일이 있는 폴더로 변경합니다.

  2. Maven을 사용하여 Spring Boot 애플리케이션을 빌드하고 실행합니다. 예를 들어:

    메모

    로컬 스프링 부팅 앱이 실행되는 시스템 시계에 따른 시간이 정확하다는 것은 매우 중요합니다. OAuth 2.0을 사용하는 경우 클록 기울이기의 허용 오차가 거의 없습니다. 심지어 3분의 시간 부정확성만으로도 [invalid_id_token] An error occurred while attempting to decode the Jwt: Jwt used before 2020-05-19T18:52:10Z와 유사한 오류로 인해 로그인이 실패할 수 있습니다. 이 글을 쓰는 시점에서 time.gov는 여러분의 시계가 실제 시간과 얼마나 차이 나는지를 보여주는 지표를 제공합니다. 앱이 +0.019초의 오차로 성공적으로 실행되었습니다.

    mvn -DskipTests clean package
    mvn -DskipTests spring-boot:run
    
  3. Maven에서 애플리케이션을 빌드하고 시작한 후 웹 브라우저에서 http://localhost:8080/ 엽니다. 로그인 페이지로 리디렉션되어야 합니다.

    웹앱 로그인 페이지입니다.

  4. 로그인과 관련된 텍스트가 있는 링크를 선택합니다. 인증 프로세스를 시작하기 위해 Azure AD B2C로 리디렉션될 것입니다.

  5. 성공적으로 로그인하면 브라우저에서 샘플 home page 표시됩니다.

    웹앱 로그인에 성공했습니다.

문제 해결

다음 섹션에서는 발생할 수 있는 몇 가지 문제를 해결하는 방법을 설명합니다.

속성에 이름이 없습니다.

샘플을 실행하는 동안 메시지 Missing attribute 'name' in attributes예외가 발생할 수 있습니다. 이 예외에 대한 로그는 다음 출력과 유사합니다.

java.lang.IllegalArgumentException: Missing attribute 'name' in attributes
at org.springframework.security.oauth2.core.user.DefaultOAuth2User.<init>(DefaultOAuth2User.java:67) ~[spring-security-oauth2-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser.<init>(DefaultOidcUser.java:89) ~[spring-security-oauth2-core-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:144) ~[spring-security-oauth2-client-5.3.6.RELEASE.jar:5.3.6.RELEASE]
at org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService.loadUser(OidcUserService.java:63) ~[spring-security-oauth2-client-5.3.6.RELEASE.jar:5.3.6.RELEASE]

이 오류가 발생하면 자습서: Azure Active Directory B2C사용자 흐름 만들기에서 만든 사용자 워크플로를 다시 확인합니다. 사용자 워크플로를 만들 때 사용자 특성 및 클레임를 선택할 때 표시 이름에 대한 특성 및 클레임을 반드시 선택하세요. 또한 application.yml 파일에서 user-name-attribute-name를 올바르게 구성하시기 바랍니다.

B2C 엔드포인트에 루프를 사용하여 로그인

이 문제는 localhost대한 오염된 쿠키로 인해 발생할 가능성이 큽니다. localhost의 쿠키를 정리하고 다시 시도해보세요.

요약

이 자습서에서는 Azure Active Directory B2C 스타터를 사용하여 새 Java 웹 애플리케이션을 만들고, 새 Azure AD B2C 테넌트를 구성하고, 새 애플리케이션을 등록한 다음, Spring 주석 및 클래스를 사용하여 웹앱을 보호하도록 애플리케이션을 구성했습니다.

리소스 정리

더 이상 필요하지 않은 경우 Azure Portal 사용하여 이 문서에서 만든 리소스를 삭제하여 예기치 않은 요금을 방지합니다.

다음 단계

Spring 및 Azure에 대해 자세히 알아보려면 Spring on Azure 설명서 센터를 계속 진행하세요.