ABOUT ME

Today
Yesterday
Total
  • 2-2. OIDC 연동 - Spring Framework
    Tutorials & Tips/WSO2 Identity Server 2022. 5. 12. 09:37

    이번 게시글은 Spring Framework 기반의 어플리케이션을 WSO2의 OIDC와 연동하여 로그인을 진행하기 위한 과정입니다. 예제 실행 환경은 다음과 같습니다.

     

    - Eclipse - Spring Framework 사용

    - JDK 1.8

    - Embedded Apache Tomcat (spring-boot-starter-tomcat-2.5.14)

    - WSO2 IS 5.11, 샘플 소스 : 로컬환경 내 구축

     

    1. Service Provider 등록

    1-1. 생성

    <그림 1> Service Provider - Add

    먼저, WSO2 의 콘솔로 접근하여 Service Provider (이하 SP) 를 등록해줍니다.

    해당 과정에서는 SP를 등록하여 Client ID / Secret 값을 발급받아야 합니다.

     

    사진과 같이, 콘솔 좌측의 표시된 부분인 Service Providers - Add를 클릭하면 그림과 같은 창이 뜨는데,

    이후 예제로 사용할 이름을 입력해준 뒤, Register를 클릭해 해당 SP를 등록해줍니다.

     

    1-2. 조회

    <그림 2> Service Provider - List

    이후 List를 클릭하면 다음과 같이 SP가 등록된걸 확인할 수 있는데, 이후 Edit를 눌러 해당 SP의 설정탭에 접근합니다.

     

    1-3. 수정

    <그림 3> Service Provider - Edit (좌) / <그림 4> OAuth/OpenID Configuration (우)

    기타 설정은 수정하지 않고, 하단의 Inbound Authentication Configuration - OAuth/OpenID Connect Configuration 탭의 Configure를 클릭해주면 우측 사진과 같은 화면이 출력되는데, 하단의 'Callback Url' 탭에 리다이렉트 할 URL을 작성해줍니다. 해당 예제에서는 "http://localhost:8080/login/oauth2/code/wso2" 를 입력해 주었습니다.

     

    <그림 5> Client ID, Client Secret

    이후 설정값을 저장하면 다음과 같이 Client Key, Secret값이 발급됩니다.

     

    2. 샘플소스 생성

    2-1. 프로젝트 생성

    <그림 6> 프로젝트 생성

     다음 구성과 같이, Spring Web, OAuth2 Client, Thymeleaf가 포함된 프로젝트를 생성하고, workspace로 import 합니다. 해당 예제에서는 start.spring.io 에서 프로젝트를 생성했습니다.

     

    2-2. 라이브러리 추가 (pom.xml)

    <!--Additional Dependencies-->
    <dependency>
    	<groupId>org.springframework.security</groupId>
    	<artifactId>spring-security-config</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.security</groupId>
    	<artifactId>spring-security-oauth2-client</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.security</groupId>
    	<artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.thymeleaf.extras</groupId>
    	<artifactId>thymeleaf-extras-springsecurity4</artifactId>
    	<version>2.1.2.RELEASE</version>
    </dependency>

    pom.xml에서 다음과 같이 라이브러리를 추가해줍니다.

     

     

    2-3. Controller 생성 (IndexController.java)

    package com.pharosinfo.oauth2loginsample;
    
    import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    
    @Controller
    public class IndexController {
        @GetMapping("/")
        public String getUserName(Model model, OAuth2AuthenticationToken token) {
            model.addAttribute("userName", token.getPrincipal().getName());
            return "index";
        }
    }

    로그인 후 화면을 출력하기 위해 indexController class를 생성해줬습니다. index 페이지에서는 로그인한 사용자의 ID를 출력하고자 하므로, View에 매핑할 userName에 token.getPrincipal().getName() 을 작성해줍니다.

     

    2-4. View 생성 (index.html)

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>OAuth2 Login </title>
    </head>
    <body>
    <div style="float: right">
        <div style="float:left">
            <span style="font-weight:bold">User: <span th:text=${userName}></span> </span>
        </div>
        <div style="float:none">&nbsp;</div>
        <div style="float:right">
            <form th:action="@{/logout}" method="post">
                <input type="submit" value="Logout"/>
            </form>
        </div>
    </div>
    <h1>OAuth 2.0 Login with Spring Security</h1>
    <div>
        You are successfully logged in as <span style="font-weight:bold" th:text="${userName}"></span>
    </div>
    </body>
    </html>

    로그인 성공 시 리턴될 View 입니다. 예시문 하단의 span 태그 안에 IndexController.java 로부터 userName이 매핑되도록 작성해줍니다.

     

    2-5. 환경변수 추가 (application.properties)

    #필수값--------------------------
    spring.thymeleaf.cache=false
    spring.security.oauth2.client.registration.wso2.client-id=<발급받은 Client ID 입력>
    spring.security.oauth2.client.registration.wso2.client-secret=<발급받은 Client Secret 입력>
    spring.security.oauth2.client.provider.wso2.authorization-uri=http://localhost:9763/oauth2/authorize
    spring.security.oauth2.client.provider.wso2.token-uri=http://localhost:9763/oauth2/token
    spring.security.oauth2.client.provider.wso2.user-info-uri=http://localhost:9763/oauth2/userinfo
    spring.security.oauth2.client.provider.wso2.jwk-set-uri=http://localhost:9763/oauth2/jwks
    
    #선택값--------------------------for tomcat logfiles
    server.tomcat.accesslog.enabled=true
    server.tomcat.accesslog.suffix=.log
    server.tomcat.accesslog.prefix=access_log
    server.tomcat.accesslog.file-date-format=.yyyy-MM-dd
    server.tomcat.basedir=tomcat
    server.tomcat.accesslog.directory=logs
    server.tomcat.accesslog.pattern=common
    
    #선택값--------------------------for view internal logs of tomcat
    logging.level.org.apache.tomcat=DEBUG
    logging.level.org.apache.catalina=DEBUG

    프로젝트 내의 application.properties 파일에 다음과 같이 Client ID, Secret, url 등 연결에 필요한 내용을 추가해줍니다. 선택값으로 표시된 server.tomcat과 관련된 설정은 디버깅을 위한 옵션으로, 필수사항은 아닙니다.

     

    2-6. Repository 작성 (OAuth2LoginConfig.java)

    package com.pharosinfo.oauth2loginsample;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    import org.springframework.security.oauth2.client.registration.ClientRegistration;
    import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
    import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
    import org.springframework.security.oauth2.core.AuthorizationGrantType;
    import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
    import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
    
    @Configuration
    public class OAuth2LoginConfig {
        private static String CLIENT_PROPERTY_KEY = "spring.security.oauth2.client.registration.wso2.";
        private static String PROVIDER_PROPERTY_KEY = "spring.security.oauth2.client.provider.wso2.";
        
        @Autowired
        private Environment env;
    
        @Bean
        public ClientRegistrationRepository
        clientRegistrationRepository() {
            return new InMemoryClientRegistrationRepository(this.WSO2ClientRegistration());
        }
    
        private ClientRegistration WSO2ClientRegistration() {
            return ClientRegistration.withRegistrationId("wso2")
                    .clientId(env.getProperty(CLIENT_PROPERTY_KEY + "client-id"))
                    .clientSecret(env.getProperty(CLIENT_PROPERTY_KEY + "client-secret"))
                    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
                    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
                    .redirectUri("{baseUrl}/login/oauth2/code/{registrationId}")
                    .scope("openid", "profile", "email", "address", "phone")
                    .authorizationUri(env.getProperty(PROVIDER_PROPERTY_KEY + "authorization-uri"))
                    .tokenUri(env.getProperty(PROVIDER_PROPERTY_KEY + "token-uri"))
                    .userInfoUri(env.getProperty(PROVIDER_PROPERTY_KEY + "user-info-uri"))
                    .userNameAttributeName(IdTokenClaimNames.SUB)
                    .jwkSetUri(env.getProperty(PROVIDER_PROPERTY_KEY + "jwk-set-uri"))
                    .clientName("WSO2")
                    .build();
        }
    }

    WSO2와 연결하기 위해 ClientRegistration 라이브러리를 사용, 환경변수를 참고하여 각 필수값을 설정해줍니다. 해당 함수에서는 scope, 로그인 페이지에 출력되는 clientName 등을 입력할 수 있습니다.

     

    3. 실행

    3-1. 메인페이지 접속

    <그림 7> Client 선택 페이지

    IDE 내에서 'Run as Spring boot App' 을 통해 해당 소스를 실행시킨 뒤 http://localhost:8080/login 으로 접속하면, 다음과 같은 화면이 출력됩니다. OAuth2LoginConfig.java 작성 당시 Repository 에 clientName 으로 등록한 'WSO2'를 확인할 수 있습니다. WSO2를 클릭하여 다음 단계인 로그인을 진행합니다.

     

     

    3-2. 로그인

    <그림 8> WSO2 로그인 페이지 (좌) / <그림 9> 접근권한 확인 페이지 (우)

    로그인 계정을 입력하면 다음과 같이 접근권한을 묻는 창이 나타납니다. OAuth2LoginConfig.java 작성 당시 Repository 에 scope 로 등록한 4개의 항목에 대한 접근권한을 묻는걸 확인할 수 있습니다. Allow를 눌러 다음 단계로 진행합니다.

     

    3-3. 로그인 확인

    <그림 10> 메인 페이지 (index.html)

    정상적으로 로그인이 진행되었다면, index.html로 이동하며 사용자 ID가 페이지에 출력되는걸 확인할 수 있습니다.

     

     

     

    4. 참고링크

     

    OAuth2 Login for Spring Boot Application with WSO2 Identity Server

    Authentication and authorization is a crosscutting concern of application development. Outsourcing the authentication to 3 rd party…

    medium.com

     

    댓글

Designed by Tistory.