gpt4 book ai didi

java - 使用 RestTemplate 的 Spring Security 身份验证

转载 作者:IT老高 更新时间:2023-10-28 13:44:56 24 4
gpt4 key购买 nike

我有 2 个 Spring Web 应用程序,它们提供 2 组独立的服务。 Web App 1 使用基于用户的身份验证实现了 Spring Security。

现在,Web App 2 需要访问 Web App 1 的服务。通常,我们会使用 RestTemplate 类向其他 Web 服务发出请求。

我们如何将Web App 2的请求中的认证凭证传递给Web App 1

最佳答案

这是一个非常适用于 Spring 3.1 和 Apache HttpComponents 4.1 的解决方案,我创建了基于此站点上的各种答案并阅读 spring RestTempalte 源代码。我分享是为了节省其他人的时间,我认为 spring 应该只内置一些这样的代码,但它没有。

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

下面是 Factory 类,它将 HttpComponents 上下文设置为在使用 RestTemplate 的每个请求上都相同。

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;
}
}

下面是 Statefull Rest 模板,您可以使用它来记住 cookie,一旦您使用它登录,它将记住 JSESSIONID 并在后续请求中发送它。

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;
}
}

这是一个代表休息客户端的类,以便您可以调用受 spring 保护的应用程序安全。

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 [\n serverUrl()=");
builder.append(serverUrl());
builder.append(", \n applicationUrl()=");
builder.append(applicationUrl());
builder.append(", \n loginUrl()=");
builder.append(loginUrl());
builder.append(", \n logoutUrl()=");
builder.append(logoutUrl());
builder.append(", \n apiUrl()=");
builder.append(apiUrl());
builder.append("\n]");
return builder.toString();
}
}

关于java - 使用 RestTemplate 的 Spring Security 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4615039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com