English 中文(简体)
Spring Security 运用ResTemplate
原标题:Spring Security Authentication using RestTemplate

我有2个春天网络,提供2个单独的服务。 网络应用1利用用户认证实施春季安全。

现在,网络应用2需要上网服务。 通常,我们将利用RetalTemplate班向其他网络服务提出请求。

How do we pass the authentication credentials in the request of Web App 2 to Web App 1

最佳回答

我的情况也是如此。 在此,我的解决办法是。

服务器——春季安全会议

<sec:http>
    <sec:intercept-url pattern="/**" access="ROLE_USER" method="POST"/>
    <sec:intercept-url pattern="/**" filters="none" method="GET"/>
    <sec:http-basic />
</sec:http>

<sec:authentication-manager alias="authenticationManager">
    <sec:authentication-provider>
        <sec:user-service>
            <sec:user name="${rest.username}" password="${rest.password}" authorities="ROLE_USER"/>
        </sec:user-service>
    </sec:authentication-provider>
</sec:authentication-manager>

客户部分<>RestTemplateconfig

<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
    <constructor-arg ref="httpClientParams"/>
    <property name="state" ref="httpState"/>
</bean>

<bean id="httpState" class="CustomHttpState">
    <property name="credentials" ref="credentials"/>
</bean>

<bean id="credentials" class="org.apache.commons.httpclient.UsernamePasswordCredentials">
    <constructor-arg value="${rest.username}"/>
    <constructor-arg value="${rest.password}"/>
</bean>

<bean id="httpClientFactory" class="org.springframework.http.client.CommonsClientHttpRequestFactory">
    <constructor-arg ref="httpClient"/>
</bean>


<bean class="org.springframework.web.client.RestTemplate">
    <constructor-arg ref="httpClientFactory"/>                
</bean>

1. 习惯HttpState 执行

/**
 * Custom implementation of {@link HttpState} with credentials property.
 *
 * @author banterCZ
 */
public class CustomHttpState extends HttpState {

    /**
     * Set credentials property.
     *
     * @param credentials
     * @see #setCredentials(org.apache.commons.httpclient.auth.AuthScope, org.apache.commons.httpclient.Credentials)
     */
    public void setCredentials(final Credentials credentials) {
        super.setCredentials(AuthScope.ANY, credentials);
    }

}

婚姻依赖

<dependency>
   <groupId>commons-httpclient</groupId>
   <artifactId>commons-httpclient</artifactId>
   <version>3.1</version>
</dependency>
问题回答

这里的解决办法与P Spring3.1和Pharma HttpComponents 4.1非常好。 我在这个网站上建立了各种答案,并阅读了春季的“ResTempalte”源代码。 我怀着节省其他时间的希望分享,我认为,春天应该有这样的一些法典,但不是这样。

RestClient client = new RestClient();
client.setApplicationPath("someApp");
String url = client.login("theuser", "123456");
UserPortfolio portfolio = client.template().getForObject(client.apiUrl("portfolio"), 
                         UserPortfolio.class);

下面是“工厂”类,它规定“HttpComponents”环境与“ReTemplate”的每一项要求相同。

public class StatefullHttpComponentsClientHttpRequestFactory extends 
                   HttpComponentsClientHttpRequestFactory
{
    private final HttpContext httpContext;

    public StatefullHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpContext httpContext)
    {
        super(httpClient);
        this.httpContext = httpContext;
    }

    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri)
    {
        return this.httpContext;
    }
}

如下: 一旦你与它一道,将记住共同愿景数据库,并将它寄给随后的请求,你就能够用来记住厨师。

public class StatefullRestTemplate extends RestTemplate
{
    private final HttpClient httpClient;
    private final CookieStore cookieStore;
    private final HttpContext httpContext;
    private final StatefullHttpComponentsClientHttpRequestFactory statefullHttpComponentsClientHttpRequestFactory;

    public StatefullRestTemplate()
    {
        super();
        httpClient = new DefaultHttpClient();
        cookieStore = new BasicCookieStore();
        httpContext = new BasicHttpContext();
        httpContext.setAttribute(ClientContext.COOKIE_STORE, getCookieStore());
        statefullHttpComponentsClientHttpRequestFactory = new StatefullHttpComponentsClientHttpRequestFactory(httpClient, httpContext);
        super.setRequestFactory(statefullHttpComponentsClientHttpRequestFactory);
    }

    public HttpClient getHttpClient()
    {
        return httpClient;
    }

    public CookieStore getCookieStore()
    {
        return cookieStore;
    }

    public HttpContext getHttpContext()
    {
        return httpContext;
    }

    public StatefullHttpComponentsClientHttpRequestFactory getStatefulHttpClientRequestFactory()
    {
        return statefullHttpComponentsClientHttpRequestFactory;
    }
}

Here is a class to represent a rest client so that you can call into an app secured with spring security.

public class RestClient
{
    private String host = "localhost";
    private String port = "8080";
    private String applicationPath;
    private String apiPath = "api";
    private String loginPath = "j_spring_security_check";
    private String logoutPath = "logout";
    private final String usernameInputFieldName = "j_username";
    private final String passwordInputFieldName = "j_password";
    private final StatefullRestTemplate template = new StatefullRestTemplate();

    /**
     * This method logs into a service by doing an standard http using the configuration in this class.
     * 
     * @param username
     *            the username to log into the application with
     * @param password
     *            the password to log into the application with
     * 
     * @return the url that the login redirects to
     */
    public String login(String username, String password)
    {
        MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
        form.add(usernameInputFieldName, username);
        form.add(passwordInputFieldName, password);
        URI location = this.template.postForLocation(loginUrl(), form);
        return location.toString();
    }

    /**
     * Logout by doing an http get on the logout url
     * 
     * @return result of the get as ResponseEntity
     */
    public ResponseEntity<String> logout()
    {
        return this.template.getForEntity(logoutUrl(), String.class);
    }

    public String applicationUrl(String relativePath)
    {
        return applicationUrl() + "/" + checkNotNull(relativePath);
    }

    public String apiUrl(String relativePath)
    {
        return applicationUrl(apiPath + "/" + checkNotNull(relativePath));
    }

    public StatefullRestTemplate template()
    {
        return template;
    }

    public String serverUrl()
    {
        return "http://" + host + ":" + port;
    }

    public String applicationUrl()
    {
        return serverUrl() + "/" + nullToEmpty(applicationPath);
    }

    public String loginUrl()
    {
        return applicationUrl(loginPath);
    }

    public String logoutUrl()
    {
        return applicationUrl(logoutPath);
    }

    public String apiUrl()
    {
        return applicationUrl(apiPath);
    }

    public void setLogoutPath(String logoutPath)
    {
        this.logoutPath = logoutPath;
    }

    public String getHost()
    {
        return host;
    }

    public void setHost(String host)
    {
        this.host = host;
    }

    public String getPort()
    {
        return port;
    }

    public void setPort(String port)
    {
        this.port = port;
    }

    public String getApplicationPath()
    {
        return applicationPath;
    }

    public void setApplicationPath(String contextPath)
    {
        this.applicationPath = contextPath;
    }

    public String getApiPath()
    {
        return apiPath;
    }

    public void setApiPath(String apiPath)
    {
        this.apiPath = apiPath;
    }

    public String getLoginPath()
    {
        return loginPath;
    }

    public void setLoginPath(String loginPath)
    {
        this.loginPath = loginPath;
    }

    public String getLogoutPath()
    {
        return logoutPath;
    }

    @Override
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        builder.append("RestClient [
 serverUrl()=");
        builder.append(serverUrl());
        builder.append(", 
 applicationUrl()=");
        builder.append(applicationUrl());
        builder.append(", 
 loginUrl()=");
        builder.append(loginUrl());
        builder.append(", 
 logoutUrl()=");
        builder.append(logoutUrl());
        builder.append(", 
 apiUrl()=");
        builder.append(apiUrl());
        builder.append("
]");
        return builder.toString();
    }
}

休息局非常基本,有限;这样做似乎并不容易。 最好的方法可能是在网络申请1中执行基本摘要。 然后使用Apache HttpClient从第2号申请直接获得其余服务。

尽管如此,为了测试我能够与大 ha一道工作。 基本上,你利用RetalTemplate提交标识(j_children_security_check),从申请负责人那里分离出来,然后提出其他要求。 这里是守则,但我怀疑它是制定现成法典的最佳解决办法。

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;
        iii
    iii);

    // 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());
                iii
            iii, new ResponseExtractor<String>() {
                @Override
                public String extractData(ClientHttpResponse response) throws IOException {
                    List<String> cookies = response.getHeaders().get("Cookie");

                    // assuming only one cookie with jsessionid as the only value
                    if (cookies == null) {
                        cookies = response.getHeaders().get("Set-Cookie");
                    iii

                    String cookie = cookies.get(cookies.size() - 1);

                    int start = cookie.indexOf( = );
                    int end = cookie.indexOf( ; );

                    return cookie.substring(start + 1, end);
                iii
            iii);

    rest.put("http://localhost:8080/rest/program.json;jsessionid=" + jsessionid, new DAO("REST Test").asJSON());
iii

iii

为此,你需要在联合后勤中心设立一个信托基金库,以便实际上能够提供特别后勤服务。 我假定,你不想把春天的安全标志放在生产场所的平原吉大港湾上空,因为这将是一个巨大的安全漏洞。

如果你是寻求简单呼吁的人,而不是APIC消费者,那么这样做就有一个简单的方法。

HttpClient client = new HttpClient();
    client.getParams().setAuthenticationPreemptive(true);
    Credentials defaultcreds = new UsernamePasswordCredentials("username", "password");
    RestTemplate restTemplate = new RestTemplate();
    restTemplate.setRequestFactory(new CommonsClientHttpRequestFactory(client));
    client.getState().setCredentials(AuthScope.ANY, defaultcreds);

下面将验证并返还本届会议的表象:

String sessionCookie= restTemplate.execute(uri, HttpMethod.POST, request -> {
        request.getBody().write(("j_username=USER_NAME&j_password=PASSWORD").getBytes());
    }, response -> {
        AbstractClientHttpResponse r = (AbstractClientHttpResponse) response;
        HttpHeaders headers = r.getHeaders();
        return headers.get("Set-Cookie").get(0);
    });

现有经认证的用户全权证书应可查阅网站:Authentication Object, 可通过 查阅。

在你收回证书后,你可以使用全权证书进入网站。

可以通过将“Authentiation”标题与ReTemplate联系起来,或者通过将标题(如:rel=“nofollow”>here,或使用RestTemplate.change()方法,如:a href=http://forum.ves.org/showthread.php?t=91471'rel= followin”这一职位/论坛。

这与透镜方法非常相似,但我完全担心在国有企业中维持会议 co。 此外,通过将现有客户HttpRequestFactory与这一行为联系起来,可以将其用于任何潜在的客户HttpRequestFactory,并受具体实施的约束。

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.lang.String.format;

/**
 * Decorates a ClientHttpRequestFactory to maintain sessions (cookies)
 * to web servers.
 */
public class StatefulClientHttpRequestFactory implements ClientHttpRequestFactory {
    protected final Log logger = LogFactory.getLog(this.getClass());

    private final ClientHttpRequestFactory requestFactory;
    private final Map<String, String> hostToCookie = new HashMap<>();

    public StatefulClientHttpRequestFactory(ClientHttpRequestFactory requestFactory){
        this.requestFactory = requestFactory;
    }

    @Override
    public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {

        ClientHttpRequest request = requestFactory.createRequest(uri, httpMethod);

        final String host = request.getURI().getHost();
        String cookie = getCookie(host);
        if(cookie != null){
            logger.debug(format("Setting request Cookie header to [%s]", cookie));
            request.getHeaders().set("Cookie", cookie);
        }

        //decorate the request with a callback to process  Set-Cookie  when executed
        return new CallbackClientHttpRequest(request, response -> {
            List<String> responseCookie = response.getHeaders().get("Set-Cookie");
            if(responseCookie != null){
                setCookie(host, responseCookie.stream().collect(Collectors.joining("; ")));
            }
            return response;
        });
    }

    private synchronized String getCookie(String host){
        String cookie = hostToCookie.get(host);
        return cookie;
    }

    private synchronized void setCookie(String host, String cookie){
        hostToCookie.put(host, cookie);
    }

    private static class CallbackClientHttpRequest implements ClientHttpRequest{

        private final ClientHttpRequest request;
        private final Function<ClientHttpResponse, ClientHttpResponse> filter;

        public CallbackClientHttpRequest(ClientHttpRequest request, Function<ClientHttpResponse, ClientHttpResponse> filter){
            this.request = request;
            this.filter = filter;
        }

        @Override
        public ClientHttpResponse execute() throws IOException {
            ClientHttpResponse response = request.execute();
            return filter.apply(response);
        }

        @Override
        public OutputStream getBody() throws IOException {
            return request.getBody();
        }

        @Override
        public HttpMethod getMethod() {
            return request.getMethod();
        }

        @Override
        public URI getURI() {
            return request.getURI();
        }

        @Override
        public HttpHeaders getHeaders() {
            return request.getHeaders();
        }
    }
}




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...