Spring Security Authentication using RestTemplate

后端 未结 7 1240
你的背包
你的背包 2020-12-02 17:58

I have 2 spring web apps that provide 2 separate set of services. Web App 1 has Spring Security implemented using a user-based authentication.

Now, Web App 2 needs

7条回答
  •  佛祖请我去吃肉
    2020-12-02 18:22

    The RestTemplate is very basic and limited; there doesn't seem to be an easy way to do this. The best way is probably to implement digest of basic auth in Web App 1. Then use Apache HttpClient directly to access the rest services from Web App 2.

    That being said, for testing I was able to work around this with a big hack. Basically you use the RestTemplate to submit the login (j_spring_security_check), parse out the jsessionid from the request headers, then submit the rest request. Here's the code, but I doubt it's the best solution for production ready code.

    public final class RESTTest {
      public static void main(String[] args) {
        RestTemplate rest = new RestTemplate();
    
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslsession) {
                return true;
            }
        });
    
        // setting up a trust store with JCA is a whole other issue
        // this assumes you can only log in via SSL
        // you could turn that off, but not on a production site!
        System.setProperty("javax.net.ssl.trustStore", "/path/to/cacerts");
        System.setProperty("javax.net.ssl.trustStorePassword", "somepassword");
    
        String jsessionid = rest.execute("https://localhost:8443/j_spring_security_check", HttpMethod.POST,
                new RequestCallback() {
                    @Override
                    public void doWithRequest(ClientHttpRequest request) throws IOException {
                     request.getBody().write("j_username=user&j_password=user".getBytes());
                    }
                }, new ResponseExtractor() {
                    @Override
                    public String extractData(ClientHttpResponse response) throws IOException {
                        List cookies = response.getHeaders().get("Cookie");
    
                        // assuming only one cookie with jsessionid as the only value
                        if (cookies == null) {
                            cookies = response.getHeaders().get("Set-Cookie");
                        }
    
                        String cookie = cookies.get(cookies.size() - 1);
    
                        int start = cookie.indexOf('=');
                        int end = cookie.indexOf(';');
    
                        return cookie.substring(start + 1, end);
                    }
                });
    
        rest.put("http://localhost:8080/rest/program.json;jsessionid=" + jsessionid, new DAO("REST Test").asJSON());
    }
    

    }

    Note for this to work, you need to create a trust store in JCA so the SSL connection can actually be made. I assume you don't want to have Spring Security's login be over plain HTTP for a production site since that would be a massive security hole.

提交回复
热议问题