zoukankan      html  css  js  c++  java
  • 使用RestTemplate Spring安全认证

    使用RestTemplate Spring安全认证



    java spring 认证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.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;
     }
     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 [
     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();
     }
    }
    


    3. 该RestTemplate是非常基本的和有限的 CodeGo.net,似乎没有成为一个简单的方法来做到这一点。最好的办法可能是在Web应用程序1消化基本身份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 Test").asJSON());
    }
    

    } 注意这个工作,你需要在JCA创建一个存储,以便在SSL连接实际上可以做。我不想让Spring Security的登录是通过纯HTTP的生产现场,因为这将是一个巨大的安全漏洞。
    4. 当前凭据应该可以在Web应用程序上1Authentication对象,这是通过访问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的

     
  • 相关阅读:
    appium自动化测试搭建
    How to install Qt Creator on Ubuntu 18.04
    Luci
    OpenWrt 根文件系统启动过程分析
    shell 杂烩
    OpenWrt Luci 调试日志输出的一种方法
    jQuery实现购物车计算价格的方法
    js实现购物车添加,减少数量
    golang-键盘录入数据
    JAVA存储机制(栈、堆、方法区详解)
  • 原文地址:https://www.cnblogs.com/zhao1949/p/6222221.html
Copyright © 2011-2022 走看看