blade-auth/pom.xml
@@ -128,6 +128,10 @@ <artifactId>httpmime</artifactId> <version>4.5.5</version> </dependency> <dependency> <groupId>org.springblade</groupId> <artifactId>blade-core-secure</artifactId> </dependency> </dependencies> <build> blade-auth/src/main/java/org/springblade/auth/config/BladeAuthorizationServerConfiguration.java
@@ -20,11 +20,12 @@ import lombok.SneakyThrows; import org.springblade.auth.constant.AuthConstant; import org.springblade.auth.granter.BladeTokenGranter; import org.springblade.auth.service.BladeClientDetailsServiceImpl; //import org.springblade.auth.service.BladeClientDetailsServiceImpl; import org.springblade.core.redis.cache.BladeRedis; import org.springblade.core.social.props.SocialProperties; import org.springblade.system.user.feign.IUserClient; import org.springblade.system.user.service.IUserService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; @@ -35,6 +36,7 @@ import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.TokenGranter; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; import org.springframework.security.oauth2.provider.token.TokenStore; @@ -50,7 +52,7 @@ * @author Chill */ @Order @Configuration(proxyBeanMethods = false) @Configuration @AllArgsConstructor @EnableAuthorizationServer public class BladeAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { @@ -101,11 +103,19 @@ */ @Override @SneakyThrows public void configure(ClientDetailsServiceConfigurer clients) { BladeClientDetailsServiceImpl clientDetailsService = new BladeClientDetailsServiceImpl(dataSource); public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // BladeClientDetailsServiceImpl clientDetailsService = new BladeClientDetailsServiceImpl(dataSource); // clientDetailsService.setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT); // clientDetailsService.setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT); clients.withClientDetails(jdbcClientDetailsService()); } @Bean public JdbcClientDetailsService jdbcClientDetailsService() { JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); clientDetailsService.setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT); clientDetailsService.setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT); clients.withClientDetails(clientDetailsService); return clientDetailsService; } @Override blade-auth/src/main/java/org/springblade/auth/config/CustomAuthenticationSuccessHandler.java
@@ -5,12 +5,17 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.Map; import static org.springframework.security.web.context.HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY; public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private String redirectUrl; private String springSecurityContextKey = SPRING_SECURITY_CONTEXT_KEY; public CustomAuthenticationSuccessHandler(String redirectUrl) { this.redirectUrl = redirectUrl; @@ -18,7 +23,13 @@ @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { // String requestURI = request.getRequestURI(); // 获取session // HttpSession session = request.getSession(); // 从authentication中获取principal信息 // Object principal = authentication.getPrincipal(); // 将principal信息存入session // session.setAttribute(this.springSecurityContextKey, principal); // String requestURI = request.getRequestURI(); Map<String, String[]> parameterMap = request.getParameterMap(); StringBuilder builder = new StringBuilder(); if (parameterMap.size()>0){ blade-auth/src/main/java/org/springblade/auth/config/SecurityConfiguration.java
@@ -1,25 +1,12 @@ /* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package org.springblade.auth.config; import lombok.AllArgsConstructor; import lombok.SneakyThrows; import org.springblade.auth.constant.Oauth2Constants; import org.springblade.auth.handle.TokenFilterHandle; import org.springblade.auth.support.BladePasswordEncoderFactories; import org.springblade.core.secure.registry.SecureRegistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; @@ -28,6 +15,7 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import javax.annotation.Resource; @@ -43,6 +31,35 @@ @Resource private Oauth2Constants oauth2Constants; @Autowired private TokenFilterHandle tokenFilterHandle; /** * 安全框架配置 */ @Bean public SecureRegistry secureRegistry() { SecureRegistry secureRegistry = new SecureRegistry(); // secureRegistry.setEnabled(false); secureRegistry.setEnabled(true); secureRegistry.excludePathPatterns("/oauth/login"); secureRegistry.excludePathPatterns("/oauth/authorize"); secureRegistry.excludePathPatterns("/oauth/form"); secureRegistry.excludePathPatterns("/blade-system/menu/routes"); secureRegistry.excludePathPatterns("/blade-system/menu/auth-routes"); secureRegistry.excludePathPatterns("/blade-system/menu/top-menu"); secureRegistry.excludePathPatterns("/blade-system/tenant/info"); secureRegistry.excludePathPatterns("/blade-flow/process/resource-view"); secureRegistry.excludePathPatterns("/blade-flow/process/diagram-view"); secureRegistry.excludePathPatterns("/blade-flow/manager/check-upload"); secureRegistry.excludePathPatterns("/doc.html"); secureRegistry.excludePathPatterns("/js/**"); secureRegistry.excludePathPatterns("/webjars/**"); secureRegistry.excludePathPatterns("/swagger-resources/**"); secureRegistry.excludePathPatterns("/druid/**"); return secureRegistry; } @Bean @Override @@ -64,19 +81,25 @@ http.formLogin() //自定义认证成功跳转 .successHandler(new CustomAuthenticationSuccessHandler(oauth2Constants.getAuthorizeUrl())) // 自定义登录页面 .loginPage(oauth2Constants.getLoginPage()) // 自定义登录接口url .loginProcessingUrl(oauth2Constants.getLoginProcessingUrl()) // 自定义登录失败处理 .failureHandler(new CustomAuthenticationFailureHandler()) ; // 认证失败自定义登录页跳转 http.exceptionHandling() .authenticationEntryPoint(new CustomAuthenticationEntryPoint(oauth2Constants.getLoginPage())); //token 校验在前 http.addFilterBefore(tokenFilterHandle, UsernamePasswordAuthenticationFilter.class); } @Override public void configure(WebSecurity web) { web.ignoring().antMatchers("/js/*.js", "/css/*.css"); web.ignoring().antMatchers("/templates/**","/js/*.js", "/css/*.css"); } } blade-auth/src/main/java/org/springblade/auth/endpoint/Test.java
New file @@ -0,0 +1,18 @@ package org.springblade.auth.endpoint; import org.springblade.core.tenant.annotation.NonDS; import org.springblade.core.tool.api.R; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @NonDS @RestController @RequestMapping("/arsn") public class Test { @GetMapping("/hello") public R test(){ return R.data("hello"); } } blade-auth/src/main/java/org/springblade/auth/handle/TokenFilterHandle.java
New file @@ -0,0 +1,48 @@ package org.springblade.auth.handle; import com.alibaba.nacos.common.utils.StringUtils; import io.jsonwebtoken.Claims; import org.springblade.core.jwt.JwtUtil; import org.springblade.core.launch.constant.TokenConstant; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * token 校验过滤器 */ @Configuration public class TokenFilterHandle extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String auth = request.getHeader("Blade-Auth"); if (!StringUtils.isBlank(auth)) { String token = JwtUtil.getToken(auth); Claims claims = JwtUtil.parseJWT(token); if (!StringUtils.isBlank(token) && null!=claims) { //判断 Token 状态 String tenantId = String.valueOf(claims.get(TokenConstant.TENANT_ID)); String userId = String.valueOf(claims.get(TokenConstant.USER_ID)); String account = String.valueOf(claims.get(TokenConstant.ACCOUNT)); String accessToken = JwtUtil.getAccessToken(tenantId, userId, token); if (token.equalsIgnoreCase(accessToken)) { UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(account, null); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); } } } filterChain.doFilter(request, response); } } blade-auth/src/main/java/org/springblade/auth/service/BladeClientDetailsServiceImpl.java
@@ -1,51 +1,51 @@ /* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package org.springblade.auth.service; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; import org.springframework.stereotype.Component; import javax.sql.DataSource; /** * 客户端信息 * * @author Chill */ @Component public class BladeClientDetailsServiceImpl extends JdbcClientDetailsService { public BladeClientDetailsServiceImpl(DataSource dataSource) { super(dataSource); } /** * 缓存客户端信息 * * @param clientId 客户端id */ @Override public ClientDetails loadClientByClientId(String clientId) { try { return super.loadClientByClientId(clientId); } catch (Exception ex) { ex.printStackTrace(); return null; } } } ///* // * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. // * // * Redistribution and use in source and binary forms, with or without // * modification, are permitted provided that the following conditions are met: // * // * Redistributions of source code must retain the above copyright notice, // * this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // * notice, this list of conditions and the following disclaimer in the // * documentation and/or other materials provided with the distribution. // * Neither the name of the dreamlu.net developer nor the names of its // * contributors may be used to endorse or promote products derived from // * this software without specific prior written permission. // * Author: Chill 庄骞 (smallchill@163.com) // */ //package org.springblade.auth.service; // //import org.springframework.security.oauth2.provider.ClientDetails; //import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; //import org.springframework.stereotype.Component; // //import javax.sql.DataSource; // ///** // * 客户端信息 // * // * @author Chill // */ //@Component //public class BladeClientDetailsServiceImpl extends JdbcClientDetailsService { // // public BladeClientDetailsServiceImpl(DataSource dataSource) { // super(dataSource); // } // // /** // * 缓存客户端信息 // * // * @param clientId 客户端id // */ // @Override // public ClientDetails loadClientByClientId(String clientId) { // try { // return super.loadClientByClientId(clientId); // } catch (Exception ex) { // ex.printStackTrace(); // return null; // } // } //} blade-auth/src/main/java/org/springblade/system/controller/ApiScopeController.java
@@ -28,7 +28,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("api-scope") @RequestMapping("/blade-system/api-scope") @Api(value = "接口权限", tags = "接口权限") public class ApiScopeController { blade-auth/src/main/java/org/springblade/system/controller/DataScopeController.java
@@ -46,7 +46,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("data-scope") @RequestMapping("/blade-system/data-scope") @Api(value = "数据权限", tags = "数据权限") public class DataScopeController { blade-auth/src/main/java/org/springblade/system/controller/DeptController.java
@@ -39,7 +39,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/dept") @RequestMapping("/blade-system/dept") @Api(value = "部门", tags = "部门") //@PreAuth(RoleConstant.HAS_ROLE_ADMIN) public class DeptController{ blade-auth/src/main/java/org/springblade/system/controller/DictBizController.java
@@ -29,7 +29,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/dict-biz") @RequestMapping("/blade-system/dict-biz") @Api(value = "业务字典", tags = "业务字典") public class DictBizController { blade-auth/src/main/java/org/springblade/system/controller/DictController.java
@@ -34,7 +34,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/dict") @RequestMapping("/blade-system/dict") @Api(value = "字典", tags = "字典") public class DictController{ blade-auth/src/main/java/org/springblade/system/controller/MenuController.java
@@ -39,7 +39,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/menu") @RequestMapping("/blade-system/menu") @Api(value = "菜单", tags = "菜单") public class MenuController { blade-auth/src/main/java/org/springblade/system/controller/ParamController.java
@@ -28,7 +28,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/param") @RequestMapping("/blade-system/param") @Api(value = "参数管理", tags = "接口") public class ParamController { blade-auth/src/main/java/org/springblade/system/controller/PostController.java
@@ -49,7 +49,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/post") @RequestMapping("/blade-system/post") @Api(value = "岗位", tags = "岗位") public class PostController { blade-auth/src/main/java/org/springblade/system/controller/RegionController.java
@@ -52,7 +52,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/region") @RequestMapping("/blade-system/region") @Api(value = "行政区划", tags = "行政区划") public class RegionController { blade-auth/src/main/java/org/springblade/system/controller/RoleController.java
@@ -37,7 +37,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/role") @RequestMapping("/blade-system/role") @Api(value = "角色", tags = "角色") //@PreAuth(RoleConstant.HAS_ROLE_ADMIN) public class RoleController { blade-auth/src/main/java/org/springblade/system/controller/SearchController.java
@@ -50,7 +50,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/search") @RequestMapping("/blade-system/search") @Api(value = "查询", tags = "查询") public class SearchController { blade-auth/src/main/java/org/springblade/system/controller/TenantController.java
@@ -59,7 +59,7 @@ @ApiIgnore @RestController @AllArgsConstructor @RequestMapping("/tenant") @RequestMapping("/blade-system/tenant") @Api(value = "租户管理", tags = "接口") public class TenantController { blade-auth/src/main/java/org/springblade/system/controller/TenantPackageController.java
@@ -46,7 +46,7 @@ */ @RestController @AllArgsConstructor @RequestMapping("/tenant-package") @RequestMapping("/blade-system/tenant-package") @Api(value = "租户产品表", tags = "租户产品表接口") public class TenantPackageController { blade-auth/src/main/java/org/springblade/system/controller/TopMenuController.java
@@ -49,7 +49,7 @@ @NonDS @RestController @AllArgsConstructor @RequestMapping("/topmenu") @RequestMapping("/blade-system/topmenu") @Api(value = "顶部菜单表", tags = "顶部菜单") //@PreAuth(RoleConstant.HAS_ROLE_ADMIN) public class TopMenuController { blade-common/pom.xml
@@ -28,6 +28,10 @@ <artifactId>blade-core-auto</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> </dependencies> <build> blade-common/src/main/java/org/springblade/common/utils/HttpClientUtils.java
New file @@ -0,0 +1,475 @@ package org.springblade.common.utils; import com.alibaba.fastjson.JSON; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.config.Registry; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.client.LaxRedirectStrategy; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.*; public class HttpClientUtils { /** * 执行有参GET请求 * * @param url * @param params * @return */ public static String doGet(String url, Map<String, String> params) { //获取httpclient客户端 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { URIBuilder builder = new URIBuilder(url); if (null != params) { for (String key : params.keySet()) { builder.setParameter(key, params.get(key)); } } HttpGet get = new HttpGet(builder.build()); response = httpclient.execute(get); if (200 == response.getStatusLine().getStatusCode()) { HttpEntity entity = response.getEntity(); resultString = EntityUtils.toString(entity, "utf-8"); } } catch (Exception e) { e.printStackTrace(); } finally { if (null != response) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != httpclient) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return resultString; } /** * 执行有参GET请求,带请求头 * * @param url 请求url * @param params 参数 * @param key 请求头Key * @param secretKey 秘钥 * @return */ public static String doGetHeader(String url, String key, String secretKey, Map<String, String> params) { //获取httpclient客户端 CloseableHttpClient httpclient = HttpClients.createDefault(); String resultString = ""; CloseableHttpResponse response = null; try { URIBuilder builder = new URIBuilder(url); if (null != params) { for (String keys : params.keySet()) { builder.addParameter(keys,params.get(keys)); //builder.setParameter(keys, params.get(keys)); } } HttpGet httpGet = new HttpGet(builder.build()); //设置请求头 httpGet.addHeader(key,secretKey); // 传输的类型 httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded"); //执行Http请求调用 response = httpclient.execute(httpGet); //判断是否请求成功返回 if (200 == response.getStatusLine().getStatusCode()) { HttpEntity entity = response.getEntity(); resultString = EntityUtils.toString(entity, "utf-8"); } } catch (Exception e) { e.printStackTrace(); } finally { if (null != response) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != httpclient) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return resultString; } /** * 执行无参GET请求 * * @param url * @return */ public static String doGet(String url) { return doGet(url, null); } /** * 执行有参POST请求 * * @param url * @param params * @return */ public static String doPost(String url,Map<String,String> headerMap,Map<String, String> params) { /** * 在4.0及以上httpclient版本中,post需要指定重定向的策略,如果不指定则按默认的重定向策略。 * * 获取httpclient客户端 */ CloseableHttpClient httpclient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build(); String resultString = ""; CloseableHttpResponse response = null; try { HttpPost post = new HttpPost(url); post.setHeader("Accept", "application/json"); post.setHeader("Accept-Encoding", "gzip"); // post.setHeader("Cache-Control", "no-cache"); // post.setHeader("Connection", "keep-alive"); post.setHeader("Content-Type", "application/json;charset=UTF-8"); if (null!=headerMap){ for (String key : params.keySet()) { post.setHeader(key, params.get(key)); } } List<NameValuePair> paramaters = new ArrayList<>(); // 设置参数 if (null != params) { for (String key : params.keySet()) { paramaters.add(new BasicNameValuePair(key, params.get(key))); } // 构造一个form表单式的实体 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramaters); // 将请求实体设置到httpPost对象中 post.setEntity(formEntity); } /** * HTTP/1.1 403 Forbidden * 原因: * 有些网站,设置了反爬虫机制 * 解决的办法: * 设置请求头,伪装浏览器 */ post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"); response = httpclient.execute(post); if (200 == response.getStatusLine().getStatusCode()) { HttpEntity entity = response.getEntity(); resultString = EntityUtils.toString(entity, "utf-8"); } } catch (Exception e) { e.printStackTrace(); } finally { if (null != response) { try { response.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != httpclient) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return resultString; } public static String doPost(String url) { return doPost(url, null,null); } // public static void main(String[] args) { // // Map<String, String> params = new HashMap<>(); // params.put("scope", "project"); // params.put("q", "数据库"); // // /** // * 有一部分网站,禁止爬虫技术访问网站。 // * // * 解决方案: // * 伪装浏览器 // * post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"); // */ // System.out.println(doPost("http://www.oschina.net/search", params)); // } /** * post 请求 header 带 秘钥 * @param url * @param appId * @param timestamp * @param transId * @param token * @param map * @return */ public static String httpPost(String url, String appId, String timestamp, String transId, String token, Map<String, Object> map) { // 返回body String res = null; // 获取连接客户端工具 CloseableHttpClient httpClient = HttpClients.createDefault(); CloseableHttpResponse httpResponse = null; // 2、创建一个HttpPost请求 HttpPost post = new HttpPost(url); // 5、设置header信息 /**header中通用属性*/ post.setHeader("Accept", "application/json"); post.setHeader("Accept-Encoding", "gzip"); post.setHeader("Content-Type", "application/json;charset=UTF-8"); HashMap<Object, Object> hashMap = new HashMap<>(4); hashMap.put("appId",appId); hashMap.put("timestamp",timestamp); hashMap.put("transId",transId); hashMap.put("token",token); String head = hashMap.toString(); post.setHeader("head", JSON.toJSONString(head)); String body = JSON.toJSONString(map); // 设置参数 if (map != null) { try { StringEntity entity1 = new StringEntity(body, "UTF-8"); entity1.setContentEncoding("UTF-8"); entity1.setContentType("json/form-data"); post.setEntity(entity1); // 7、执行post请求操作,并拿到结果 httpResponse = httpClient.execute(post); // 获取结果实体 HttpEntity entity = httpResponse.getEntity(); if (entity != null) { // 按指定编码转换结果实体为String类型 res = EntityUtils.toString(entity, "UTF-8"); } try { httpResponse.close(); httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } } return res; } public static SSLContext createIgnoreVerifySSL() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { SSLContext sc = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); return sc; } //适用于post请求并传送form-data数据(同样适用于post的Raw类型的application-json格式) public static String postParams(String url, String appKey, String appKeyValue, Map<String, String> map) { SSLContext sslcontext = null; try { sslcontext = createIgnoreVerifySSL(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } // 设置协议http和https对应的处理socket链接工厂的对象 Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.INSTANCE) .register("https", new SSLConnectionSocketFactory(sslcontext)) .build(); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); //创建自定义的httpclient对象 CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build(); HttpPost post = new HttpPost(url); // post.setHeader(appKey, appKeyValue); CloseableHttpResponse res = null; try { List<NameValuePair> nvps = new ArrayList<NameValuePair>(); Set<String> keySet = map.keySet(); for (String key : keySet) { nvps.add(new BasicNameValuePair(key, map.get(key))); } post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8")); res = client.execute(post); HttpEntity entity = res.getEntity(); return EntityUtils.toString(entity, "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { try { res.close(); client.close(); } catch (IOException e) { e.printStackTrace(); } } return ""; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param params 请求的参数集合 * @return 远程资源的响应结果 */ @SuppressWarnings("unused") public static String sendPost(String url, Map<String, String> params) { OutputStreamWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { URL realUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // POST方法 conn.setRequestMethod("POST"); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.connect(); // 获取URLConnection对象对应的输出流 out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // 发送请求参数 if (params != null) { StringBuilder param = new StringBuilder(); for (Map.Entry<String, String> entry : params.entrySet()) { if (param.length() > 0) { param.append("&"); } param.append(entry.getKey()); param.append("="); param.append(entry.getValue()); } out.write(param.toString()); } // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result.append(line); } } catch (Exception e) { e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result.toString(); } }