다음을 통해 공유


Azure Active Directory B2C에서 MSAL4J를 사용하여 Java WebSphere 앱에 로그인 사용

이 문서에서는 MsAL4J(Microsoft Authentication Library for Java)를 사용하여 Azure AD B2C(Azure Active Directory B2C)에 대해 사용자를 인증하는 Java Servlet 애플리케이션을 보여 줍니다.

다음 다이어그램은 앱의 토폴로지입니다.

앱의 토폴로지 다이어그램

앱은 MSAL4J를 사용하여 사용자를 로그인하고 Azure AD B2C에서 ID 토큰을 가져옵니다. ID 토큰은 사용자가 Azure AD B2C 테넌트에 대해 인증됨을 증명합니다.

필수 조건

  • JDK 버전 8 이상
  • Maven 3
  • Azure AD B2C 테넌트. 자세한 내용은 자습서: Azure Active Directory B2C 테넌트 만들기를 참조 하세요.
  • Azure AD B2C 테넌트에 있는 사용자 계정입니다.

권장 사항

샘플 설정

다음 섹션에서는 샘플 애플리케이션을 설정하는 방법을 보여줍니다.

샘플 리포지토리 복제 또는 다운로드

샘플을 복제하려면 Bash 창을 열고 다음 명령을 사용합니다.

git clone https://github.com/Azure-Samples/ms-identity-java-servlet-webapp-authentication.git
cd 1-Authentication/sign-in-b2c

또는 ms-identity-java-servlet-webapp-authentication 리포지토리로 이동한 다음, .zip 파일로 다운로드하여 하드 드라이브에 추출합니다.

Important

Windows에서 파일 경로 길이 제한을 방지하려면 리포지토리를 하드 드라이브 루트 근처의 디렉터리에 복제하거나 추출합니다.

Azure AD B2C 테넌트에 샘플 애플리케이션 등록

샘플은 테스트 목적으로 미리 등록된 애플리케이션과 함께 제공됩니다. 사용자 고유의 Azure AD B2C 테넌트 및 애플리케이션을 사용하려면 다음 섹션의 단계에 따라 Azure Portal에서 애플리케이션을 등록하고 구성합니다. 그렇지 않은 경우 샘플 실행에 대한 단계를 계속 진행합니다.

애플리케이션을 만들 Azure AD B2C 테넌트 선택

테넌트 선택하려면 다음 단계를 사용합니다.

  1. Azure Portal에 로그인합니다.

  2. 계정이 둘 이상의 Azure AD B2C 테넌트에 있는 경우 Azure Portal의 모서리에서 프로필을 선택한 다음 디렉터리 전환을 선택하여 세션을 원하는 Azure AD B2C 테넌트로 변경합니다.

사용자 흐름 및 사용자 지정 정책 만들기

등록, 로그인, 프로필 편집 및 암호 재설정과 같은 일반적인 사용자 흐름을 만들려면 자습서: Azure Active Directory B2C에서 사용자 흐름 만들기를 참조하세요.

Azure Active Directory B2C에서도 사용자 지정 정책을 만드는 것이 좋지만 이 자습서의 범위를 벗어납니다.

외부 ID 공급자 추가

자습서: Azure Active Directory B2C에서 애플리케이션에 ID 공급자 추가를 참조하세요.

앱 등록(ms-identity-b2c-java-servlet-webapp-authentication)

앱을 등록하려면 다음 단계를 사용합니다.

  1. Azure Portal로 이동하여 Azure AD B2C를 선택합니다.

  2. 탐색 창에서 앱 등록을 선택한 다음, 새 등록을 선택합니다.

  3. 표시되는 애플리케이션 등록 페이지에서 다음 애플리케이션 등록 정보를 입력합니다.

    • 이름 섹션에서 앱 사용자에게 표시할 의미 있는 애플리케이션 이름(예ms-identity-b2c-java-servlet-webapp-authentication: .)을 입력합니다.
    • 지원되는 계정 유형에서 모든 조직 디렉터리 및 개인 Microsoft 계정(예: Skype, Xbox, Outlook.com)의 계정을 선택합니다.
    • 리디렉션 URI(선택 사항) 섹션에서 콤보 상자에서 웹을 선택하고 다음 리디렉션 URIhttp://localhost:8080/ms-identity-b2c-java-servlet-webapp-authentication/auth_redirect를 입력합니다.
  4. 등록을 선택하여 애플리케이션을 만듭니다.

  5. 앱의 등록 페이지에서 나중에 사용할 애플리케이션(클라이언트) ID 값을 찾아 복사합니다. 앱의 구성 파일 또는 파일에서 이 값을 사용합니다.

  6. 저장을 선택하여 변경 내용을 저장합니다.

  7. 앱의 등록 페이지에서 탐색 창에서 인증서 및 비밀을 선택하여 비밀을 생성하고 인증서를 업로드할 수 있는 페이지를 엽니다.

  8. 클라이언트 비밀 섹션에서 새 클라이언트 비밀을 선택합니다.

  9. 설명(예: 앱 비밀)을 입력합니다.

  10. 사용 가능한 기간 중 하나(1년, 2년 후 또는 만료 안 됨) 중 하나를 선택합니다.

  11. 추가를 선택합니다. 생성된 값이 표시됩니다.

  12. 이후 단계에서 사용할 생성된 값을 복사하고 저장합니다. 코드의 구성 파일에 이 값이 필요합니다. 이 값은 다시 표시되지 않으며 다른 어떤 수단으로도 검색할 수 없습니다. 따라서 다른 화면 또는 창으로 이동하기 전에 Azure Portal에서 저장해야 합니다.

앱 등록을 사용하도록 앱 구성(ms-identity-b2c-java-servlet-webapp-authentication)

다음 단계를 사용하여 앱을 구성합니다.

참고 항목

다음 단계에서 ClientID 는 같거나 AppId같습니다Application ID.

  1. IDE에서 프로젝트를 엽니다.

  2. ./src/기본/resources/authentication.properties 파일을 엽니다.

  3. aad.clientId 속성을 찾고 Azure Portal에서 기존 값을 애플리케이션 ID 또는 clientId 애플리케이션으로 ms-identity-b2c-java-servlet-webapp-authentication 바꿉니다.

  4. aad.secret 속성을 찾고 기존 값을 Azure Portal에서 애플리케이션을 만드는 ms-identity-b2c-java-servlet-webapp-authentication 동안 저장한 값으로 바꿉니다.

  5. aad.scopes 속성을 찾고 기존 application clientId를 이 섹션의 1단계에서 배치한 값으로 aad.clientId 바꿉다.

  6. aad.authority 속성을 찾고 첫 번째 인스턴스를 fabrikamb2c Azure Portal에서 애플리케이션을 만든 ms-identity-b2c-java-servlet-webapp-authentication Azure AD B2C 테넌트 이름으로 바꿉니다.

  7. aad.authority 속성을 찾고 두 번째 인스턴스를 fabrikamb2c Azure Portal에서 애플리케이션을 만든 ms-identity-b2c-java-servlet-webapp-authentication Azure AD B2C 테넌트 이름으로 바꿉니다.

  8. aad.signInPolicy 속성을 찾아서 Azure Portal에서 애플리케이션을 만든 Azure AD B2C 테넌트에서 만든 등록/로그인 사용자 흐름 정책의 ms-identity-b2c-java-servlet-webapp-authentication 이름으로 바꿉니다.

  9. aad.passwordResetPolicy 속성을 찾아서 Azure Portal에서 애플리케이션을 만든 Azure AD B2C 테넌트에서 만든 암호 재설정 사용자 흐름 정책의 ms-identity-b2c-java-servlet-webapp-authentication 이름으로 바꿉니다.

  10. aad.editProfilePolicy 속성을 찾아서 Azure Portal에서 애플리케이션을 만든 Azure AD B2C 테넌트에서 만든 프로필 사용자 흐름 편집 정책의 ms-identity-b2c-java-servlet-webapp-authentication 이름으로 바꿉니다.

샘플 빌드

Maven을 사용하여 샘플을 빌드하려면 샘플에 대한 pom.xml 파일이 포함된 디렉터리로 이동한 다음 다음 명령을 실행합니다.

mvn clean package

이 명령은 다양한 애플리케이션 서버에서 실행할 수 있는 .war 파일을 생성합니다.

샘플 실행

이러한 지침에서는 WebSphere를 설치하고 서버를 설정했다고 가정합니다. 기본 서버 설정을 위해 Azure Virtual MachinesWebSphere 애플리케이션 서버(기존) 클러스터 배포에서 지침을 사용할 수 있습니다.

WebSphere에 배포하기 전에 다음 단계를 사용하여 샘플 자체에서 몇 가지 구성을 변경한 다음 패키지를 빌드하거나 다시 빌드합니다.

  1. 다음 예제와 같이 앱의 authentication.properties 파일로 이동하고 사용하려는 서버 URL 및 포트 번호로 값을 app.homePage 변경합니다.

    # app.homePage is by default set to dev server address and app context path on the server
    # for apps deployed to azure, use https://your-sub-domain.azurewebsites.net
    app.homePage=https://<server-url>:<port-number>/msal4j-servlet-auth/
    
  2. 이 파일을 저장한 후 다음 명령을 사용하여 앱을 다시 빌드합니다.

    mvn clean package
    
  3. 코드 빌드가 완료되면 .war 파일을 대상 서버의 파일 시스템에 복사합니다.

또한 Azure Portal에서 인증 탭의 리디렉션 URI으로 설정하는 Azure 앱 등록을 동일하게 변경해야 합니다.

  1. 개발자용 Microsoft ID 플랫폼의 앱 등록 페이지로 이동합니다.

  2. 검색 상자를 사용하여 앱 등록을 검색합니다(예: .) java-servlet-webapp-authentication.

  3. 이름을 선택하여 앱 등록을 엽니다.

  4. 메뉴에서 인증을 선택합니다.

  5. - 리디렉션 URI 섹션에서 URI 추가를 선택합니다.

  6. 앱의 URI를 입력하고 /auth/redirect추가합니다(예https://<server-url>:<port-number>/auth/redirect: .).

  7. 저장을 선택합니다.

다음 단계를 사용하여 WebSphere의 통합 솔루션 콘솔을 사용하여 샘플을 배포합니다.

  1. 애플리케이션 탭에서 새 애플리케이션, 새 엔터프라이즈 애플리케이션을 선택합니다.

  2. 빌드한 .war 파일을 선택한 다음 웹 모듈 설치 단계의 맵 컨텍스트 루트에 도착할 때까지 다음 선택합니다. 다른 기본 설정은 괜찮을 것입니다.

  3. 컨텍스트 루트의 경우 샘플 구성/Azure 앱 등록에서 설정한 '리디렉션 URI'의 포트 번호 뒤와 동일한 값으로 설정합니다. 즉, 리디렉션 URI인 http://<server-url>:9080/msal4j-servlet-auth/경우 컨텍스트 루트가 되어야 msal4j-servlet-auth합니다.

  4. 마침을 선택합니다.

  5. 애플리케이션 설치가 완료되면 애플리케이션 탭의 WebSphere 엔터프라이즈 애플리케이션 섹션으로 이동합니다.

  6. 애플리케이션 목록에서 설치한 .war 파일을 선택한 다음 배포 시작을 선택합니다.

  7. 배포가 완료되면 애플리케이션으로 http://<server-url>:9080/{whatever you set as the context root} 이동하면 애플리케이션을 볼 수 있습니다.

샘플 탐색

다음 단계를 사용하여 샘플을 탐색합니다.

  1. 로그인 또는 로그아웃된 상태 화면 중앙에 표시됩니다.
  2. 모서리에서 상황에 맞는 단추를 선택합니다. 이 단추는 앱을 처음 실행할 때 로그인을 읽습니다.
  3. 다음 페이지에서 지침을 따르고 선택한 ID 공급자의 계정으로 로그인합니다.
  4. 이제 상황에 맞는 단추에 로그아웃이 표시되고 사용자 이름이 표시됩니다.
  5. ID 토큰 세부 정보를 선택하여 ID 토큰의 디코딩된 클레임 중 일부를 확인합니다.
  6. 프로필을 편집할 수도 있습니다. 링크를 선택하여 표시 이름, 거주지 및 직업과 같은 세부 정보를 편집합니다.
  7. 모서리의 단추를 사용하여 로그아웃합니다.
  8. 로그아웃한 후 토큰 세부 정보 페이지에 http://localhost:8080/ms-identity-b2c-java-servlet-webapp-authentication/auth_token_details대한 다음 URL로 이동합니다. 여기서는 ID 토큰 클레임 대신 앱에서 401: unauthorized 오류를 표시하는 방법을 확인할 수 있습니다.

코드 정보

이 샘플에서는 MSAL4J를 사용하여 사용자를 Azure AD B2C 테넌트에 로그인하는 방법을 보여 줍니다.

콘텐츠

다음 표에서는 샘플 프로젝트 폴더의 내용을 보여 줍니다.

파일/폴더 설명
AuthHelper.java 인증을 위한 도우미 함수입니다.
Config.java 시작 시 실행되며 속성 판독기 및 로거를 구성합니다.
authentication.properties Microsoft Entra ID 및 프로그램 구성.
AuthenticationFilter.java 인증되지 않은 요청을 보호된 리소스로 401 페이지로 리디렉션합니다.
MsalAuthSession 를 사용하여 HttpSession인스턴스화됩니다. 모든 MSAL 관련 세션 특성을 세션 특성에 저장합니다.
____Servlet.java 사용 가능한 모든 엔드포인트는 ____Servlet.java 끝나는 .java 클래스에 정의됩니다.
CHANGELOG.md 샘플의 변경 내용 목록입니다.
CONTRIBUTING.md 샘플에 기여하기 위한 지침입니다.
라이센스 샘플에 대한 라이선스입니다.

ConfidentialClientApplication

ConfidentialClientApplication 인스턴스는 다음 예제와 같이 AuthHelper.java 파일에 만들어집니다. 이 개체는 Azure AD B2C 권한 부여 URL을 만드는 데 도움이 되며 액세스 토큰에 대한 인증 토큰을 교환하는 데도 도움이 됩니다.

IClientSecret secret = ClientCredentialFactory.createFromSecret(SECRET);
confClientInstance = ConfidentialClientApplication
                     .builder(CLIENT_ID, secret)
                     .b2cAuthority(AUTHORITY + policy)
                     .build();

인스턴스화에는 다음 매개 변수가 사용됩니다.

  • 앱의 클라이언트 ID입니다.
  • 기밀 클라이언트 애플리케이션에 대한 요구 사항인 클라이언트 암호입니다.
  • Azure AD B2C 기관은 등록, 로그인, 프로필 편집 또는 암호 재설정에 적합한 UserFlowPolicy 권한과 연결되었습니다.

이 샘플에서 이러한 값은 Config.java 파일의 속성 판독기를 사용하여 authentication.properties 파일에서 습니다.

단계별 안내

다음 단계에서는 앱의 기능에 대한 연습을 제공합니다.

  1. 로그인 프로세스의 첫 번째 단계는 Azure Active Directory B2C 테넌트에 대한 엔드포인트에 요청을 /authorize 보내는 것입니다. MSAL4J ConfidentialClientApplication 인스턴스는 권한 부여 요청 URL을 생성하는 데 사용되며 앱은 다음 예제와 같이 브라우저를 이 URL로 리디렉션합니다.

    final ConfidentialClientApplication client = getConfidentialClientInstance(policy);
    final AuthorizationRequestUrlParameters parameters = AuthorizationRequestUrlParameters
        .builder(REDIRECT_URI, Collections.singleton(SCOPES)).responseMode(ResponseMode.QUERY)
        .prompt(Prompt.SELECT_ACCOUNT).state(state).nonce(nonce).build();
    
    final String redirectUrl = client.getAuthorizationRequestUrl(parameters).toString();
    Config.logger.log(Level.INFO, "Redirecting user to {0}", redirectUrl);
    resp.setStatus(302);
    resp.sendRedirect(redirectUrl);
    

    다음 목록에서는 이 코드의 기능을 설명합니다.

    • AuthorizationRequestUrlParameters: AuthorizationRequestUrl을 빌드하기 위해 설정해야 하는 매개 변수입니다.

    • REDIRECT_URI: Azure AD B2C는 사용자 자격 증명을 수집한 후 인증 코드와 함께 브라우저를 리디렉션합니다.

    • SCOPES: 범위는 애플리케이션에서 요청한 권한입니다.

      일반적으로 세 가지 범위는 openid profile offline_access ID 토큰 응답을 수신하는 데 충분합니다. 그러나 MSAL4J는 Azure AD B2C의 모든 응답에도 액세스 토큰을 포함해야 합니다.

      Azure AD B2C가 액세스 토큰과 ID 토큰을 분배하려면 요청에 추가 리소스 범위가 포함되어야 합니다. 이 앱에는 실제로 외부 리소스 범위가 필요하지 않으므로 액세스 토큰을 받기 위해 자체 클라이언트 ID를 네 번째 범위로 추가합니다.

      authentication.properties 파일에서 앱에서 요청한 전체 범위 목록을 찾을 수 있습니다.

    • ResponseMode.QUERY: Azure AD B2C는 응답을 HTTP POST 요청의 양식 매개 변수로 반환하거나 HTTP GET 요청의 쿼리 문자열 매개 변수로 반환할 수 있습니다.

    • Prompt.SELECT_ACCOUNT: Azure AD B2C는 사용자에게 인증하려는 계정을 선택하도록 요청해야 합니다.

    • state: 앱이 각 토큰 요청의 세션으로 설정하고 해당 Azure AD B2C 리디렉션 콜백을 받은 후 제거되는 고유 변수입니다. 상태 변수는 Azure AD B2C 요청 /auth_redirect endpoint 이 이 앱과 이 세션에서 시작된 Azure AD B2C 권한 부여 요청에서 실제로 전송되도록 하여 CSRF 공격을 방지합니다. 이 작업은 AADRedirectServlet.java 파일에서 수행됩니다.

    • nonce: 앱이 각 토큰 요청의 세션에 설정하고 해당 토큰을 받은 후 제거되는 고유 변수입니다. 이 nonce는 Azure AD B2C를 분배한 결과 토큰으로 전사되어 토큰 재생 공격이 발생하지 않도록 합니다.

  2. 사용자에게 Azure Active Directory B2C에서 로그인 프롬프트가 표시됩니다. 로그인 시도가 성공하면 사용자의 브라우저가 앱의 리디렉션 엔드포인트로 리디렉션됩니다. 이 엔드포인트에 대한 유효한 요청에는 권한 부여 코드포함되어 있습니다.

  3. 그런 다음 인스턴스는 ConfidentialClientApplication 다음 예제와 같이 Azure Active Directory B2C에서 ID 토큰 및 액세스 토큰에 대해 이 권한 부여 코드를 교환합니다.

    final AuthorizationCodeParameters authParams = AuthorizationCodeParameters
                        .builder(authCode, new URI(REDIRECT_URI))
                        .scopes(Collections.singleton(SCOPES)).build();
    
    final ConfidentialClientApplication client = AuthHelper
            .getConfidentialClientInstance(policy);
    final Future<IAuthenticationResult> future = client.acquireToken(authParams);
    final IAuthenticationResult result = future.get();
    

    다음 목록에서는 이 코드의 기능을 설명합니다.

    • AuthorizationCodeParameters: ID 및/또는 액세스 토큰에 대한 권한 부여 코드를 교환하기 위해 설정해야 하는 매개 변수입니다.
    • authCode: 리디렉션 엔드포인트에서 받은 권한 부여 코드입니다.
    • REDIRECT_URI: 이전 단계에서 사용된 리디렉션 URI를 다시 전달해야 합니다.
    • SCOPES: 이전 단계에서 사용된 범위를 다시 전달해야 합니다.
  4. 성공하면 acquireToken 다음 예제와 같이 토큰 클레임이 추출되고 nonce 클레임이 세션에 저장된 nonce에 대해 유효성이 검사됩니다.

    parseJWTClaimsSetAndStoreResultInSession(msalAuth, result, serializedTokenCache);
    validateNonce(msalAuth)
    processSuccessfulAuthentication(msalAuth);
    
  5. nonce의 유효성이 성공적으로 검사되면 다음 예제와 같이 클래스에서 노출하는 메서드를 활용하여 인증 상태 서버 쪽 세션에 MsalAuthSession 배치됩니다.

    msalAuth.setAuthenticated(true);
    msalAuth.setUsername(msalAuth.getIdTokenClaims().get("name"));
    

자세한 정보

이 시나리오 및 기타 시나리오에서 OAuth 2.0 프로토콜이 작동하는 방식에 대한 자세한 내용은 Microsoft Entra ID에 대한 인증 시나리오를 참조하세요.

다음 단계

Azure Virtual Machines의 기존 WebSphere에 Java WebSphere 앱 배포