使用RestTemplate Spring安全认证
来源:互联网 发布:2017省市区数据库json 编辑:程序博客网 时间:2024/05/16 05:47
使用RestTemplate Spring安全认证
javaspring 认证authentication 安全spring-security
我有提供2个独立的一整套服务2 Spring的web应用程序。 Web应用程序1具有Spring Security的使用认证。 现在,Web应用程序2需要访问Web应用程序1的服务。通常情况下,我们的RestTemplate类来发送请求到其他网络服务。 我们如何通过在Web应用程序2要求的身份验证凭据到Web应用程序1
本文地址 :CodeGo.net/238843/
-------------------------------------------------------------------------------------------------------------------------
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>
客户端端RestTemplate配置<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>
自定义的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); }}
Maven的依赖<dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version></dependency>
2. 这里是一个解决方案,它工作得很好,春季3.1和Apache HttpComponents 4.1我创建了这个网站为基础的答案和阅读的springRestTempalte源代码。我在救人的希望分享我觉得spring应该只是有这样的内置代码,但它没有。
RestClient client = new RestClient();client.setApplicationPath("someApp");String url = client.login("theuser", "123456");UserPortfolio portfolio = client.template().getForObject(client.apiUrl("portfolio"), UserPortfolio.class);
下面是设置了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; }}
下面是有状态的rest模板,你的cookies,一旦你与它会将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; }}
这里是一个类来表示一个REST客户端端,让你可以调用抵押和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 " CodeGo.net + 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(); }}
3. 该RestTemplate是非常基本的和有限的 CodeGo.net,似乎没有成为一个简单的方法来做到这一点。最好的办法可能是在Web应用程序1消化基本身份验证的。 Apache的HttpClient的直接从Web应用程序2访问REST服务。 话虽这么说,对于测试我能解决这个一个大劈。基本上,RestTemplate提交登录(j_spring_security_check),解析出JSESSIONID从请求头,然后提交,其余请求。下面的代码,但我怀疑它是为生产做好准备代码的最佳解决方案。
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(" CodeGo.net HttpMethod.POST, new RequestCallback() { @Override public void doWithRequest(ClientHttpRequest request) throws IOException { request.getBody().write("j_username=user&j_password=user".getBytes()); } }, 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"); } String cookie = cookies.get(cookies.size() - 1); int start = cookie.indexOf('='); int end = cookie.indexOf(';'); return cookie.substring(start + 1, end); } }); rest.put(" CodeGo.net + jsessionid, new DAO("REST Test").asJSON());}
} 注意这个工作,你需要在JCA创建一个存储,以便在SSL连接实际上可以做。我不想让Spring Security的登录是通过纯HTTP的生产现场,因为这将是一个巨大的安全漏洞。4. 当前凭据应该可以在Web应用程序上1
Authentication
对象,这是通过访问SecurityContext
(例如,你可以通过调用检索SecurityContextHolder.getContext().getAuthentication()
)。 当您检索凭据,您将它们访问Web应用程序2。 您可以通过扩展它与decorator(如下所述)通“Authentiation”头与RestTemplateRestTemplate.exchange()
方法,如在本论坛发表的文章中描述。5. 有一个简单的方法来做到这一点的情况下,你是谁在寻找一个简单的调用,而不是一个API
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);
本文标题 :使用RestTemplate Spring安全认证
本文地址 :CodeGo.net/238843/
1. 在C ++坏分配异常
2. 其中这些存储方法是最快的?
3. VSS到SVN-库 我们终于从Visual Source S
4. 我怎样才能确保嵌套事务相互独立的承诺?
5. 使用URL路由时,asp.net多的Page_Load事件的用户控件
6. 如何显示使用servlet和JSP的PDF文件? [关闭]
7. 如何张贴到墙上的朋友使用Facebook的图形API为iPhone
8. jQuery的添加的iFrame与内容
9. 如何阅读收到的邮件使用C#
10. 十六进制转换在awk中为十进制或sed的
0 0
- 使用RestTemplate Spring安全认证
- 使用Spring RestTemplate测试
- spring RestTemplate使用
- 如何使用 Spring RestTemplate
- 使用spring security实现oauth安全认证
- 为什么使用spring Shiro去做安全认证
- Spring中RestTemplate使用例子
- spring/springboot RestTemplate使用笔记
- spring RestTemplate
- spring restTemplate
- Spring RestTemplate
- Controller 使用RestTemplate进行单元测试 spring mvc
- spring中 使用restTemplate访问rest接口
- 使用spring RestTemplate进行rest接口测试
- spring rest mvc使用RestTemplate调用
- 使用Spring RestTemplate解析RESTful服务
- Spring RestTemplate使用ByteArrayResource上传方式
- 使用Spring RestTemplate解析RESTful服务
- SAP 采购订单税金抓取方法
- 使用ajax来进行前后传送数据(django框架、Python语言)
- nohttp阅读笔记
- 《机器学习实战》之kNN-笔记1
- 银行系统的开发精华1
- 使用RestTemplate Spring安全认证
- 同时max(),min()取最大 最小值 在mysql和Oracle中的差别
- 随便——单身狗的圣诞节
- 程序员的七大痛点
- 特征处理(Feature Processing)
- 开源代码分析
- 引用
- rxjava的SubscribeOn流程的关键代码
- ML_1 supervised learning and unsupervised learning