[java] Apache Shiro와 웹소켓 통합

Apache Shiro는 자바 기반의 보안 프레임워크로, 인증, 인가, 세션 관리 등의 기능을 제공합니다. 웹 애플리케이션에서 Shiro를 사용하면 쉽게 사용자 인증 및 인가를 구현할 수 있습니다.

이번에는 Apache Shiro를 사용하여 웹소켓 통합을 구현하는 방법에 대해 알아보겠습니다. 웹소켓은 서버와 클라이언트 사이의 실시간 양방향 통신을 제공합니다. Apache Shiro와 웹소켓을 통합하면 보안 기능을 적용한 웹소켓 애플리케이션을 구축할 수 있습니다.

Shiro 웹소켓 의존성 추가

Shiro 웹소켓 통합을 위해서는 다음과 같이 의존성을 추가해야 합니다.

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-websockets</artifactId>
    <version>1.7.1</version>
</dependency>

Shiro 웹소켓 구성

웹소켓 통합을 위해 Shiro의 DefaultWebsocketSubjectFactory를 사용하여 Subject를 생성합니다. 또한, DefaultWebSocketMessageResolver를 사용하여 웹소켓 메시지의 처리를 담당합니다. 다음은 Shiro 웹소켓을 구성하는 예제 코드입니다.

import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.websocket.DefaultWebsocketSubjectFactory;
import org.apache.shiro.web.websocket.DefaultWebSocketMessageResolver;
import org.apache.shiro.web.websocket.WebSocketMessageResolver;

import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

public class ShiroWebSocketConfigurator extends ServerEndpointConfig.Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
        super.modifyHandshake(config, request, response);
        // Shiro의 DefaultWebsocketSubjectFactory를 사용하여 Subject 생성
        config.getUserProperties().put(DefaultWebsocketSubjectFactory.USER_PROPERTIES_SUBJECT_FACTORY,
                new DefaultWebsocketSubjectFactory());
    }

    @Override
    public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
        // Shiro의 DefaultWebSocketMessageResolver를 사용하여 메시지 처리
        WebSocketMessageResolver resolver = new DefaultWebSocketMessageResolver();
        return endpointClass.cast(resolver);
    }
}

ShiroWebSocketConfigurator 클래스는 Shiro의 DefaultWebsocketSubjectFactoryDefaultWebSocketMessageResolver를 사용하여 웹소켓을 구성합니다. 이 클래스는 ServerEndpointConfig.Configurator를 상속받아 필요한 메소드를 구현합니다.

웹소켓 엔드포인트에 Shiro 적용

이제 Shiro를 사용하여 보안 기능을 적용한 웹소켓 엔드포인트를 구현해보겠습니다. 다음은 Shiro를 적용한 웹소켓 엔드포인트의 예제 코드입니다.

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/websocket", configurator = ShiroWebSocketConfigurator.class)
public class MyWebSocketEndpoint {
    @OnOpen
    public void onOpen(Session session) {
        // 현재 사용자의 Subject 가져오기
        Subject currentUser = SecurityUtils.getSubject();
        // 인증된 사용자인지 확인
        if (currentUser.isAuthenticated()) {
            // 웹소켓 세션을 사용자와 연결
            currentUser.getSession().setAttribute("websocketSession", session);
        } else {
            // 인증되지 않은 사용자는 접속을 거부
            session.close();
        }
    }
    
    // ... 생략 ...
}

@ServerEndpoint 어노테이션의 configurator 속성에는 앞서 구현한 ShiroWebSocketConfigurator 클래스를 설정하여 Shiro를 적용합니다. 엔드포인트 클래스에서는 Shiro를 사용하여 현재 사용자의 Subject를 가져온 후, 인증된 사용자인지 확인하여 웹소켓 세션을 사용자와 연결합니다. 인증되지 않은 사용자의 경우 접속을 거부합니다.

결론

Apache Shiro를 사용하여 웹소켓 통합을 구현하는 방법에 대해 알아보았습니다. Shiro를 이용하면 보안 기능을 쉽게 적용한 웹소켓 애플리케이션을 개발할 수 있습니다. 자세한 내용은 Apache Shiro 웹사이트를 참고하시기 바랍니다.