Rest API: 基本认证和摘要认证

用spring security实现Rest API的基本认证(Basic)和摘要认证(Digest):

Basic 认证

1. server - spring security配置

package com.pechen.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    public final static String REALM="MY_REALM";
     
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")
        .and().withUser("test").password("test").roles("USER");
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	http.csrf().disable()
        	.authorizeRequests()
	        .anyRequest().authenticated()
	        .and().httpBasic().realmName(REALM).authenticationEntryPoint(getBasicAuthEntryPoint());
//	        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);//We don't need sessions to be created.
    }
    
    @Bean
    public CustomBasicAuthenticationEntryPoint getBasicAuthEntryPoint(){
        return new CustomBasicAuthenticationEntryPoint();
    }
    
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        // altough this seems like useless code,
        // its required to prevend spring boot auto-configuration
        return super.authenticationManagerBean();
    }

}
package com.pechen.config;

import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
 
public class CustomBasicAuthenticationEntryPoint extends BasicAuthenticationEntryPoint {
 
	@Override
	public void commence(final HttpServletRequest request, final HttpServletResponse response,
			final AuthenticationException authException) throws IOException, ServletException {
		response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
		response.addHeader("WWW-Authenticate", "Basic realm=\"" + getRealmName() + "\"");

		PrintWriter writer = response.getWriter();
		writer.println("HTTP Status 401 : " + authException.getMessage());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		setRealmName(WebSecurityConfig.REALM);
		super.afterPropertiesSet();
	}
}

2. server - rest api

package com.pechen.rest;

import java.util.Map;

import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * Authentication service.
 */
@RestController
@RequestMapping(path = "/")
public class RestService {
    @RequestMapping(path = "/login", method = RequestMethod.GET)
    public String login(@RequestHeader Map<String, Object> headers){
    	return "Login success...";
    }
}

3. client - rest template(加上Authorization的头部即可)

package com.pechen.test;

import java.util.Base64;

import org.junit.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class AuthServiceTest {
	private HttpHeaders getHeaders(){
		String plainCredentials="admin:admin";
		String base64Credentials = Base64.getEncoder().encodeToString(plainCredentials.getBytes());
		
		HttpHeaders headers = new HttpHeaders();
		headers.add("Authorization", "Basic " + base64Credentials);
		return headers;
	}

	@Test
	public void testLogin() {
		RestTemplate restTemplate = new RestTemplate();
		HttpEntity<String> request = new HttpEntity<String>(getHeaders());
		ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/login", HttpMethod.GET,
				request, String.class);
		System.out.println(response.getBody());
	}
}

Digest 认证

1. server - spring security配置

package com.pechen.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.www.DigestAuthenticationFilter;
 
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    public final static String REALM="MY_REALM";
     
    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN")
        .and().withUser("test").password("test").roles("USER");
    }
     
    @Override
    protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable()
			.authorizeRequests()
			.anyRequest().authenticated()
			.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
			.and().exceptionHandling().authenticationEntryPoint(getDigestEntryPoint())
			.and().addFilter(getDigestAuthenticationFilter(getDigestEntryPoint()));
    	
    }
    
	@Bean
	public MyDigestAuthenticationEntryPoint getDigestEntryPoint() {
		MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint = new MyDigestAuthenticationEntryPoint();
		digestAuthenticationEntryPoint.setKey("mykey");
		digestAuthenticationEntryPoint.setNonceValiditySeconds(120);
		digestAuthenticationEntryPoint.setRealmName(REALM);
		return digestAuthenticationEntryPoint;
	}

	public DigestAuthenticationFilter getDigestAuthenticationFilter(
			MyDigestAuthenticationEntryPoint digestAuthenticationEntryPoint) throws Exception {
		DigestAuthenticationFilter digestAuthenticationFilter = new DigestAuthenticationFilter();
		digestAuthenticationFilter.setAuthenticationEntryPoint(digestAuthenticationEntryPoint);
		digestAuthenticationFilter.setUserDetailsService(userDetailsServiceBean());
		return digestAuthenticationFilter;
	}
 
	@Override
	@Bean
	public UserDetailsService userDetailsServiceBean() throws Exception {
		return super.userDetailsServiceBean();
	}
}
package com.pechen.config;

import org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint;

public class MyDigestAuthenticationEntryPoint extends DigestAuthenticationEntryPoint {
	
	@Override
	public void afterPropertiesSet() throws Exception{
		super.afterPropertiesSet();
		setRealmName(WebSecurityConfig.REALM);
	}
}
2. server - rest api 同上
3. client - 配置rest template使用Digest认证

package com.pechen.rest;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

public class RestTempleteConfig {

	public RestTemplate getRestTemplate() {
		CloseableHttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider())
				.useSystemProperties().build();
		HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactoryDigestAuth(
				client);

		return new RestTemplate(requestFactory);
	}

	private CredentialsProvider provider() {
		CredentialsProvider provider = new BasicCredentialsProvider();
		UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("admin", "admin");
		provider.setCredentials(AuthScope.ANY, credentials);
		return provider;
	}
}
package com.pechen.rest;

import java.net.URI;
import org.apache.http.HttpHost;
import org.apache.http.client.AuthCache;
import org.apache.http.client.HttpClient;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.auth.DigestScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;

public class HttpComponentsClientHttpRequestFactoryDigestAuth extends HttpComponentsClientHttpRequestFactory {
	 
    public HttpComponentsClientHttpRequestFactoryDigestAuth(HttpClient client) {
        super(client);
    }
 
    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
        return createHttpContext(uri);
    }
 
    private HttpContext createHttpContext(URI uri) {
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate DIGEST scheme object, initialize it and add it to the local auth cache
        DigestScheme digestAuth = new DigestScheme();
        // If we already know the realm name
        digestAuth.overrideParamter("realm", "myrealm");
        HttpHost targetHost = new HttpHost(uri.getHost(), uri.getPort());
        authCache.put(targetHost, digestAuth);
 
        // Add AuthCache to the execution context
        BasicHttpContext localcontext = new BasicHttpContext();
        localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
        return localcontext;
    }
}
4. 使用rest template发送请求

package com.pechen.test;

import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import jdk.nashorn.internal.ir.annotations.Ignore;

public class RestClient {
	
	@Test
	public void whenSecuredRestApiIsConsumed_then200OK() {
	    RestTemplate restTemplate = new RestTempleteConfig().getRestTemplate();
	    String uri = "http://localhost:8080/login";
	    ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
	    System.out.println(entity.getStatusCode());
	    System.out.println(entity.getBody());
	}
}








  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ASIHTTPRequest对CFNetwork API进行了封装,并且使用起来非常简单,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中。ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互。 ASIHTTPRequest功能很强大,主要特色如下: l 通过简单的接口,即可完成向服务端提交数据和从服务端获取数据的工作 l 下载的数据,可存储到内存中或直接存储到磁盘中 l 能上传本地文件到服务端 l 可以方便的访问和操作请求和返回的Http头信息 l 可以获取到上传或下载的进度信息,为应用程序提供更好的体验 l 支持上传或下载队列,并且可获取队列的进度信息 l 支持基本摘要和NTLM身份认证,在同一会话中授权凭证会自动维持,并且可以存储在Keychain(Mac和iOS操作系统的密码管理系统)中 l 支持Cookie l 当应用(iOS 4+)在后台运行时,请求可以继续运行 l 支持GZIP压缩数据 l 内置的ASIDownloadCache类,可以缓存请求返回的数据,这样即使没有网络也可以返回已经缓存的数据结果 l ASIWebPageRequest –可以下载完整的网页,包括包含的网页、样式表、脚本等资源文件,并显示在UIWebView /WebView中。任意大小的页面都可以无限期缓存,这样即使没有网络也可以离线浏览 l 支持客户端证书 l 支持通过代理发起Http请求 l 支持带宽限制。在iOS平台,可以根据当前网络情况来自动决定是否限制带宽,例如当使用WWAN(GPRS/Edge/3G)网络时限制,而当使用WIFI时不做任何限制 l 支持断点续传 l 支持同步和异步请求
目录 1.简介 2.如何使用示例代码 3.我为什么要学习Wicket? 3.1。我们都喜欢意大利面:-) ... 3.2。面向组件的框架 - 概述 3.3。面向组件的Web开发框架的优点 3.4。Wicket与其他面向组件的框架相比 威克特说“你好世界!” 4.1。Wicket分发和模块 4.2。Wicket应用程序的配置 4.3。HomePage类 4.4。Wicket链接 4.5。摘要 5. Wicket作为页面布局管理器 5.1。页眉,页脚,左侧菜单,内容等... 5.2。这是继承! 5.3。划分et impera! 5.4。使用wicket标记继承:扩展标记 5.5。摘要 6.保持对HTML的控制 6.1。隐藏或禁用组件 6.2。修改标签属性 6.3。生成标记属性“id” 6.4。使用WebMarkupContainer创建内嵌面板 6.5。使用标记片段 6.6。将标题内容添加到最终页面 6.7。在我们的页面/面板中使用存根标记 6.8。如何仅渲染组件主体 6.9。用wicket隐藏装饰元素:enclosure标签 6.10。使用Border包围现有标记 6.11。摘要 7.组件生命周期 7.1。组件的生命周期阶段 7.2。组件生命周期的钩子方法 7.3。初始化阶段 7.4。渲染阶段 7.5。删除阶段 7.6。独立舞台 7.7。摘要 8.页面版本控制和缓存 8.1。有状态页面与无状态页面 8.2。有状态页面 8.3。无状态页面 8.4。摘要 9.在请求处理的引擎盖下 9.1。类应用和请求处理 9.2。请求和响应类 9.3。请求处理的“主管” - RequestCycle 9.4。会话类 9.5。异常处理 9.6。摘要 10. Wicket链接和URL生成 10.1。PageParameters 10.2。可收藏的链接 10.3。使用标记wicket自动创建可收藏的链接:链接 10.4。外部链接 10.5。无状态链接 10.6。生成结构清晰的URL 10.7。摘要 11. Wicket模型和表格 11.1。什么是模特? 11.2。IModel和Lambda 11.3。模型和JavaBeans 11.4。Wicket形式 11.5。组件DropDownChoice 11.6。模型链 11.7。可拆卸型号 11.8。在组件中使用多个模型 11.9。使用型号! 11.10。摘要 12. Wicket详细说明 12.1。默认表单处理 12.2。表单验证和反馈消息 12.3。输入值转换 12.4。使用JSR 303验证 12.5。使用IFormSubmittingComponent提交表单 12.6。嵌套表格 12.7。多行文字输入 12.8。上传文件 12.9。使用FormComponentPanel创建复杂的表单组件 12.10。无国籍形式 12.11。使用单选按钮和复选框 12.12。使用ListMultipleChoices和Palette选择多个值 12.13。摘要 13.使用中继器显示多个项目 13.1。RepeatingView组件 13.2。ListView组件 13.3。RefreshingView组件 13.4。可分页的中继器 13.5。摘要 14.组件排队 14.1。标记层次结构和代码 14.2。改进了汽车组件 14.3。组件什么时候出列? 14.4。排队的限制 14.5。摘要 15.与Wicket的国际化 15.1。本土化 15.2。Wicket的本地化 15.3。捆绑查找算法 15.4。组件选择的本地化 15.5。国际化和模型 15.6。摘要 16. Wicket的资源管理 16.1。静态与动态资源 16.2。资源参考 16.3。包资源 16.4。向页眉部分添加资源 16.5。上下文相关资源 16.6。资源依赖性 16.7。使用资源包聚合多个资源 16.8。将JavaScript放在页面正文中 16.9。标题贡献者定位 16.10。自定义资源 16.11。安装资源 16.12。Lambda支持 16.13。共享资源 16.14。自定义资源加载 16.15。CssHeaderItem和JavaScriptHeaderItem压缩 16.16。NIO资源 16.17。资源通过模型得出 16.18。摘要 17.与JavaScript集成的示例 17.1。我们想做什么...... 17.2。......以及我们将如何做到这一点 17.3。摘要 18. Wicket高级主题 18.1。通过行为丰富组件 19.使用AJAX 19.1。如何使用AJAX组件和行为 19.2。内置AJAX组件 19.3。内置的AJAX行为 19.4。使用活动指示器 19.5。AJAX请求属性和调用侦听器 19.6。创建自定义AJAX调用侦
### 回答1: 好的。 使用 Python 与 Salesforce REST API 进行交互的代码大致如下: 首先,你需要安装 Salesforce REST API 的 Python 客户端库,例如 `simple-salesforce`。你可以使用 `pip` 安装这个库: ``` pip install simple-salesforce ``` 然后,你需要在 Salesforce 中创建一个连接并获取相应的访问令牌。有关如何进行这些操作的详细信息,请参阅 Salesforce 的文档。 接下来,你可以使用 Python 代码来访问 Salesforce REST API。例如,你可以使用以下代码检索 Salesforce 中的联系人: ```python from simple_salesforce import Salesforce # 创建 Salesforce 连接 sf = Salesforce(username='YOUR_USERNAME', password='YOUR_PASSWORD', security_token='YOUR_SECURITY_TOKEN') # 检索联系人 contacts = sf.Contact.select('Id, FirstName, LastName') for contact in contacts: print(f'{contact["FirstName"]} {contact["LastName"]}') ``` 你还可以使用以下代码在 Salesforce 中创建新的联系人: ```python # 创建新联系人 new_contact = { 'FirstName': 'John', 'LastName': 'Doe', 'Email': '[email protected]' } sf.Contact.create(new_contact) ``` 这只是一些简单的示例代码。Salesforce REST API 提供了更多功能,你可以在 Salesforce 的文档中了解有关详细信息。 ### 回答2: Python是一种高级编程语言,而Salesforce REST API是一种用于与Salesforce平台进行通信和交互的接口。以下是使用Python编写与Salesforce REST API交互的代码示例: 1. 导入所需的库和模块: ```python import requests import json ``` 2. 定义Salesforce连接信息: ```python base_url = 'https://your_salesforce_instance.salesforce.com' api_version = 'vXX.X' # 根据你的Salesforce实例的版本选择 access_token = 'your_access_token' ``` 3. 发送GET请求以获取记录: ```python def get_records(object_name): url = f'{base_url}/services/data/{api_version}/sobjects/{object_name}' headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json' } response = requests.get(url, headers=headers) if response.status_code == 200: records = response.json() return records else: return None ``` 4. 发送POST请求以创建记录: ```python def create_record(object_name, record_data): url = f'{base_url}/services/data/{api_version}/sobjects/{object_name}' headers = { 'Authorization': f'Bearer {access_token}', 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, data=json.dumps(record_data)) if response.status_code == 201: new_record = response.json() return new_record else: return None ``` 请注意,上述代码只是示例代码,你需要根据自己的实际需求进行适当的修改和定制。你需要替换`your_salesforce_instance.salesforce.com`为你的Salesforce实例的主机名,并根据你的访问权限获取和设置正确的访问令牌(access token)。此外,你还需要根据所需操作的对象名称(object name)和记录数据(record data)进行调整。 希望以上示例代码能帮助你开始使用Python与Salesforce REST API进行交互。 ### 回答3: Python和Salesforce REST API的代码可以用来与Salesforce平台进行数据交互。 1. 导入必要的Python模块: ```python import requests import json ``` 2. 设置Salesforce REST API的访问凭证: ```python username = 'your_username' password = 'your_password' security_token = 'your_security_token' client_id = 'your_client_id' client_secret = 'your_client_secret' grant_type = 'password' ``` 3. 获取访问令牌(access token): ```python data = { 'grant_type': grant_type, 'client_id': client_id, 'client_secret': client_secret, 'username': username, 'password': password + security_token } response = requests.post('https://login.salesforce.com/services/oauth2/token', data=data) response_data = json.loads(response.text) access_token = response_data['access_token'] instance_url = response_data['instance_url'] ``` 4. 使用访问令牌调用Salesforce REST API: ```python headers = { 'Authorization': 'Bearer ' + access_token, 'Content-Type': 'application/json' } # 示例:创建一个新的联系人 new_contact = { 'LastName': 'Smith', 'FirstName': 'John', 'Email': '[email protected]' } create_contact_url = instance_url + '/services/data/v51.0/sobjects/Contact/' response = requests.post(create_contact_url, headers=headers, data=json.dumps(new_contact)) response_data = json.loads(response.text) created_contact_id = response_data['id'] ``` 以上是使用Python访问Salesforce REST API基本代码示例。确保用户名、密码、安全令牌、客户端ID和客户端密钥正确,并根据实际需求进行相应的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值