복붙노트

[SPRING] 자바 클라이언트로 스프링 보안 구현하기

SPRING

자바 클라이언트로 스프링 보안 구현하기

고객 입장에서

기본 POST 또는 GET 메서드를 사용하여 원격 서버에 연결하는 Java 응용 프로그램이 있습니다.

URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-type", "text/xml; charset=" + ENCODING);

conn.connect();
conn.getOutputStream().write(data.getBytes(ENCODING));
conn.getOutputStream().close();

(이 코드를 변경할 수는 없지만 메서드를 호출 할 때 urlStr과 데이터가 서버로 전송됩니다.)

[편집] : 클라이언트는 Java 클라이언트 또는 다른 클라이언트 (C ++, objective-c, ..)가 될 수 있습니다. 여기서 중요한 것은 URL의 내용뿐 아니라 내 게시물의 본문에만 액세스 할 수 있다는 것입니다.

서버 측

내 서버 측에서는 스프링 보안 (SecurityContext 및 세션 지속성)을 구현하고 싶습니다.

세션 ID에 대한 정보를 보유하고있는 웹 애플리케이션 인 경우 스프링 보안은 브라우저의 쿠키를 기반으로한다는 것을 알고 있습니다. 하지만 제 경우에는 브라우저가 없습니다.

고맙습니다.

[편집하다]

@ zagyi가 지적한 바와 같이 URL을 사용하여 세션 토큰을 Spring에 전달할 수는 있지만 여전히 방법을 파악할 수는 없습니다.

해결법

  1. ==============================

    1.URL에 jsessionid를 전달하는 것은 다음과 같이 url 끝에이를 추가하는 것입니다.

    URL에 jsessionid를 전달하는 것은 다음과 같이 url 끝에이를 추가하는 것입니다.

    http://localhost:8080/example/auth/login;jsessionid=A06F00609BBA8A4C2B005FB25F90C4C9
    

    쿠키를 허용하지 않도록 브라우저를 구성한 경우이 작업을 볼 수 있습니다.이 경우 서버는 url에 세션 ID를 자동으로 포함합니다 (기본 tomcat 구성을 가정 할 때). 이 주제는이 질문에서도 논의됩니다.

  2. ==============================

    2.이를위한 클라이언트 측 솔루션이있을 수 있습니다.

    이를위한 클라이언트 측 솔루션이있을 수 있습니다.

    우리가 상호 작용할 수있는 행동 포인트는 다음과 같습니다.

    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    

    JSESSIONID를 처리 할 자체 (랩핑 된) HttpURLConnection을 제공 할 것입니다. 그러나 불행히도 우리는 조금 더 시작해야합니다.

    트릭은 새로운 프로토콜을 등록하는 것입니다. "xhttp", 실제 "http"프로토콜 연결을 래핑하는 데 사용합니다. 따라서 URL은 다음과 같습니다.

    xhttp://www.example.com/...
    

    먼저 URLStreamHandlerFactory 클래스를 정의합니다.

    public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
        public URLStreamHandler createURLStreamHandler(String protocol) {
            if ("xhttp".equals(protocol)) {
                return new MyURLStreamHandler();
            }
            return null;
        }
    }
    

    Java (또는 응용 프로그램) 초기화 시간에 설정할 수 있습니다. JVM 당 한 번만 수행 할 수 있습니다.

    URLStreamHandlerFactory fac = new MyURLStreamHandlerFactory();
    URL.setURLStreamHandlerFactory(fac);
    

    이제 My URLStreamHandler를 살펴 보겠습니다.

    public class MyURLStreamHandler extends URLStreamHandler {
        @Override
        protected URLConnection openConnection(URL url) throws IOException {
            return new MyHttpURLConnection(url);
        }
    }
    

    이것은 아주 간단합니다. 우리는 우리 자신의 연결을 만듭니다. 더러운 것을 해보 죠.

    public final class MyHttpURLConnection extends HttpURLConnection {
        private HttpURLConnection conn;
        public MyHttpURLConnection(URL url) throws MalformedURLException, IOException {
            super(url);
            String newUrlString = url.toExternalForm().substring(1);
            conn = (HttpURLConnection) new URL(newUrlString).openConnection();
        }
        @Override
        public void disconnect() {
            conn.disconnect();
        }
        @Override
        public boolean usingProxy() {
            return false;
        }
        @Override
        public void connect() throws IOException {
            conn.connect();
            conn.setRequestProperty("JSESSIONID", "X");
        }
    }
    

    그리고 voilá, 우리는 우리의 연결에 접근 할 수 있었고, JSESSIONID 헤더를 설정할 수있었습니다.

    필요한 것은 클래스를 컴파일하고, 클래스 파일을 클라이언트 jar에 추가하고, 위 코드가 실행되는 동일한 JVM에서 init 코드를 실행하는 것입니다.

    할 수 없다면 또 다른 가능성이 있습니다 : 클라이언트 Java 응용 프로그램에 다음 시스템 매개 변수를 설정하십시오.

    -Djava.protocol.handler.pkgs=com.example.myprotocol
    

    이 경우 com.example.myprotocol.xhttp (프로토콜 이름과 같은 xhttp)를 만들고 MyURLStreamHandler 클래스의 이름을 com.example.myprotocol.xhttp.Handler로 변경하십시오. 이것은 프로토콜 해석자가 찾을 고정 된 이름입니다. 이 java.protocol.handler.pkgs 등록 정보는 보안 관리자가 확인합니다.

  3. from https://stackoverflow.com/questions/15096764/implementing-spring-security-with-java-client by cc-by-sa and MIT license