Ubuntu下OpenVPN客户端配置教程

 安全  Ubuntu下OpenVPN客户端配置教程已关闭评论
1月 152017
 

一般来说,提供Web服务的Linux服务器是很少需要连接OpenVPN的,但是个人Linux计算机在很多时候就需要连接OpenVPN了。比如以Linux为开发环境,需要连接公司的OpenVPN等等。 

本文将以Ubuntu系统为例,介绍在终端下连接远程OpenVPN服务的方法。 

安装OpenVPN

首先需要安装OpenVPN客户端。一般来说直接使用apt-get即可。执行如下命令安装:

1 [[email protected] ~]# apt-get install openvpn

稍等片刻将自动安装好openvpn需要的软件包。安装完成后,应该出现

/etc/openvpn/

文件夹。 

配置OpenVPN

作为客户端,OpenVPN并没有特定的配置文件,而是由服务器提供方给出一个配置文件。对于认证,OpenVPN提供了两种认证方法:基于用户名/密码的认证与SSL证书认证。用户名/密码的认证方法无法(或较难)限制一个账号同时连接多个客户端,而采用证书,则可保证同一证书同一时间只能有一个客户端连接。当然,这些都是由服务器端决定的,不需要客户端进行选择。

首先将OpenVPN服务器提供商发给你的配置文件解压,并将所有文件都复制到 /etc/openvpn/中。

这些文件中至少包含一个.ovpn文件,需要手动创建该文件,如:client.ovpn;如果服务器需要证书认证,则应该还存在另外三个证书文件。

看懂OpenVPN配置格式。下面是一个.ovpn配置示例:

client
dev tap
proto tcp-client
remote 192.168.135.75 1194
resolv-retry infinite
nobind
mute-replay-warnings
redirect-gateway
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client.crt
key /etc/openvpn/client.key
comp-lzo
verb 4

一般来说,红色的内容可能需要你进行修改。将红色的内容修改成这三个文件的实际位置。然后保存即可。 

连接OpenVPN

在配置好.ovpn文件后,执行

openvpn /etc/openvpn/client.ovpn

即可连接服务器了(注意该目录下对应文件的权限)。注意,上面的参数应该换成你的配置文件实际位置。

此时,终端会回显很多连接日志。如果连接不成功,则可以通过这些日志来确定出错位置。如果要断开,只需要通过Ctrl+C强制终止即可。

上面的命令在实际中并不方便,因为它要占用一个独立的终端。在测试成功后,使用以下命令即可在后台连接OpenVPN:

openvpn /etc/openvpn/client.ovpn > /dev/null &

值得称赞的是,openvpn非常智能,在连接异常中断、无法连接服务器、断网的情况下,它会自动重连。因此,如果希望开机即自动连接OpenVPN,或者是VPN常年在线,则可将上述命令行加入

/etc/rc.local

中。注意,命令末尾的&符号不能省略,否则将可能阻塞系统的正常启动。

转自:http://www.linuxidc.com/Linux/2013-06/86562.htm

Getting “Cannot ioctl TUNSETIFF tun: Operation not permitted” when trying to connect to OpenVPN解决

 安全  Getting “Cannot ioctl TUNSETIFF tun: Operation not permitted” when trying to connect to OpenVPN解决已关闭评论
1月 152017
 

使用命令      openvpn client.ovpn     启动openvpn时出现下面的错误:

… Getting “Cannot ioctl TUNSETIFF tun: Operation not permitted” when trying to connect to OpenVPN …

其实只要使用  sudo openvpn client.ovpn 就可以了

Spring security oauth2最简单入门环境搭建

 java, 安全  Spring security oauth2最简单入门环境搭建已关闭评论
6月 032016
 

Spring security oauth2最简单入门环境搭建,网上找到的文章,强烈推荐:http://wwwcomy.iteye.com/blog/2230265

基本需求: 
用户A希望授权网站B能获取自己在网站appDemo的一个资源,资源的地址是 
http://localhost:8080/appDemo/resource/getUserInfo 

使用的框架及版本: 

  • spring-webmvc 3.2.8
  • spring-security-web 3.2.6
  • spring-security-oauth2 2.0.7 (这是到2015.7为止的最新版本,和1.0有些小区别,我也在这上面卡了一段时间)
  • Pom文件见附件整个项目源码。 

    准备材料(附件都已经包括): 

  • 搭建一个springMVC+springSecurity的最简单环境,并且自定义一个login.jsp
  • 写一个controller和Jsp,充当用户的受保护资源
  • 写两个jsp作为scope选择确认页面
  • 我们要做的 
    仅仅是配置spring security的配置文件就可以了~一点代码都不用写,数据库也不用连。 

    我会从client信息开始,把整个配置文件串起来,最后我会讲appDemo使用的方法,和以下的配置联系起来 

  • 网站B在网站appDemo的”用户”(注意这里和用户A没半毛钱关系)信息,即client_id和client_secret配置:
  • Xml代码  收藏代码

    1. <authentication-manager id=“clientAuthenticationManager”>  
    2.         <authentication-provider user-service-ref=“oauth2ClientDetailsUserService” />  
    3.     </authentication-manager>  
    4.     <beans:bean id=“oauth2ClientDetailsUserService”  
    5.     class=“org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService”>  
    6.         <beans:constructor-arg ref=“clientDetailsService” />  
    7.     </beans:bean>  
    8. <oauth2:client-details-service id=“clientDetailsService”>  
    9.         <oauth2:client client-id=“m1”  
    10.             authorized-grant-types=“password,authorization_code,refresh_token,implicit”  
    11.             secret=“s1” scope=“read,write,trust” authorities=“ROLE_CLIENT, ROLE_TRUSTED_CLIENT”  
    12.             resource-ids=“pic-resource” />  
    13.     </oauth2:client-details-service>  

    注意命名空间,可以看到client配置和spring security传统的用户配置是非常像的。 
    这里配置了网站B在appDemo中的client_id,client_secret,scope,权限和授权类型,资源ID,那这个资源ID是个啥呢? 

  • 资源filter配置:
  • Xml代码  收藏代码

    1. <oauth2:resource-server id=“picResourceServer”  
    2.         resource-id=“pic-resource” token-services-ref=“tokenServices” />  

    配置这个,除了资源定位(id),还为了给我们的资源加上一个自定义的OAuth过滤器,这个过滤器主要是为了网站B在访问资源的时候验证Access Token。然后出现了两个分支: 
    1.配token service 
    2.配资源 

  • 先讲Token配置:
  • Xml代码  收藏代码

    1. <beans:bean id=“tokenServices”  
    2.         class=“org.springframework.security.oauth2.provider.token.DefaultTokenServices”>  
    3.         <beans:property name=“tokenStore” ref=“tokenStore” />  
    4.         <beans:property name=“supportRefreshToken” value=“true” />  
    5.         <beans:property name=“clientDetailsService” ref=“clientDetailsService” />  
    6.     </beans:bean>  
    7.     <beans:bean id=“tokenStore”  
    8.         class=“org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore”>  
    9.     </beans:bean>  

    我们把Token存在内存里,摆脱数据库依赖。想象一下,为了生成和client相关的token,肯定需要把上面提到的ClientService配置进去 

  • 资源和资源的保护
  • Xml代码  收藏代码

    1. <http pattern=“/resource/**” create-session=“never”  
    2.         entry-point-ref=“oauth2AuthenticationEntryPoint”  
    3.         access-decision-manager-ref=“oauth2AccessDecisionManager”>  
    4.         <anonymous enabled=“false” />  
    5.         <intercept-url pattern=“/resource/**” access=“ROLE_USER,SCOPE_READ” />  
    6.         <custom-filter ref=“picResourceServer” before=“PRE_AUTH_FILTER” />  
    7.         <access-denied-handler ref=“oauthAccessDeniedHandler” />  
    8.     </http>  

    这是spring security的传统配置了,除了我们刚才提到的资源filter,还配置了认证失败、授权失败的处理,和判断是否可访问的”access decision manager” 

  • 认证失败,授权失败
  • Xml代码  收藏代码

    1. <beans:bean id=“oauth2AuthenticationEntryPoint”  
    2.         class=“org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint” />  
    3.   
    4.     <beans:bean id=“oauthAccessDeniedHandler”  
    5.         class=“org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler” />  

    这个没什么好解释的了,其实作为demo也可以不配,毕竟我们应该会一路按能跑通的先跑。 

  • access decision manager
  • Xml代码  收藏代码

    1. <beans:bean id=“oauth2AccessDecisionManager”  
    2.         class=“org.springframework.security.access.vote.UnanimousBased”>  
    3.         <beans:constructor-arg>  
    4.             <beans:list>  
    5.                 <beans:bean  
    6.                     class=“org.springframework.security.oauth2.provider.vote.ScopeVoter” />  
    7.                 <beans:bean class=“org.springframework.security.access.vote.RoleVoter” />  
    8.                 <beans:bean  
    9.                     class=“org.springframework.security.access.vote.AuthenticatedVoter” />  
    10.             </beans:list>  
    11.         </beans:constructor-arg>  
    12.     </beans:bean>  

    也是传统的配置方法了,多了个oauth2里面特有的scope投票机制。 

    好,到现在为止,OAuth2 Server所需要的所有龙珠都已经集齐,接下来就可以召唤神龙了 

  • 出来吧!神龙
  • Xml代码  收藏代码

    1. <oauth2:authorization-server  
    2.         client-details-service-ref=“clientDetailsService” token-services-ref=“tokenServices”  
    3.         user-approval-handler-ref=“oauthUserApprovalHandler”  
    4.         user-approval-page=“oauth_approval” error-page=“oauth_error”>  
    5.         <oauth2:authorization-code />  
    6.         <oauth2:implicit />  
    7.         <oauth2:refresh-token />  
    8.         <oauth2:client-credentials />  
    9.         <oauth2:password />  
    10.     </oauth2:authorization-server>  
    11.   
    12.     <beans:bean id=“oauthUserApprovalHandler”  
    13.         class=“org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler” />  

    还差两步: 
    1.网站B来申请Token时候的认证和权限设置: 

    Xml代码  收藏代码

    1. <http pattern=“/oauth/token” create-session=“stateless”  
    2.         authentication-manager-ref=“clientAuthenticationManager”  
    3.         entry-point-ref=“oauth2AuthenticationEntryPoint”>  
    4.         <intercept-url pattern=“/oauth/token” access=“IS_AUTHENTICATED_FULLY” />  
    5.         <anonymous enabled=“false” />  
    6.         <http-basic entry-point-ref=“oauth2AuthenticationEntryPoint” />  
    7.         <custom-filter ref=“clientCredentialsTokenEndpointFilter”  
    8.             before=“BASIC_AUTH_FILTER” />  
    9.         <access-denied-handler ref=“oauthAccessDeniedHandler” />  
    10.     </http>  
    11.   
    12.     <beans:bean id=“clientCredentialsTokenEndpointFilter”  
    13.         class=“org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter”>  
    14.         <beans:property name=“authenticationManager” ref=“clientAuthenticationManager” />  
    15.     </beans:bean>  

    2.作为屌丝用户A,认证放在配置最后了(也应该放在前面那个http的后面,因为这里有个全局匹配了) 

    Xml代码  收藏代码

    1. <http access-denied-page=“/login.jsp?error=true”  
    2.         authentication-manager-ref=“authenticationManager”>  
    3.         <intercept-url pattern=“/oauth/**” access=“ROLE_USER” />  
    4.         <intercept-url pattern=“/**” access=“IS_AUTHENTICATED_ANONYMOUSLY” />  
    5.         <form-login login-page=“/login.jsp”  
    6.             authentication-failure-url=“/login.jsp?error=true”  
    7.             default-target-url=“/index.jsp” />  
    8.         <anonymous />  
    9.     </http>  
    10.   
    11.     <authentication-manager alias=“authenticationManager”>  
    12.         <authentication-provider>  
    13.             <user-service id=“userService”>  
    14.                 <user name=“admin” password=“admin” authorities=“ROLE_USER” />  
    15.             </user-service>  
    16.         </authentication-provider>  
    17.     </authentication-manager>  

    写到这里,我默默预览了一下,估计群众们看到这句话大都是拖滚轴下来的。 

    不过配置真的挺长,不花篇幅真讲不清楚。 

    最后把大致流程和配置关联一下: 

    • *.用户要授权网站B获取appDemo资源
    • 1.网站B把用户跳转到appDemo/oauth/authorize?client_id=m1&redirect_uri=http%3a%2f%2flocalhost%3a8080%2f&response_type=code&scope=read
    • Spring Security Oauth2有一个controller:AuthorizationEndpoint处理这个请求,这个是不用配置的。 但是在controller处理之前,appDemo发现,我擦嘞,用户还没登录啊(见屌丝用户A认证配置)!于是先跳转到登录界面让用户登录。 

    • 2.用户登录成功后,跳转到了scope选择确认页面(见出现吧!神龙)。
    • 3.appDemo生成了Authorization Code并跳转回网站B(其实神龙的authorization-code这种配置方式有其他的配置项,可以选填Authorzation code service)
    • 4.网站B拿到了code,向appDemo请求accessToken(appDemo/oauth/token?code=g6hW13&client_id=m1&client_secret=s1&grant_type=authorization_code&redirect_uri=http%3a%2f%2flocalhost%3a8080%2f)
    • 网站B的client认证配置起作用了,AccessDecisionManager起作用了,资源信息起作用了,Token生成也起作用了。

    • 5.最后网站B通过access token访问资源,资源和资源的保护配置起作用了。

    具体的使用流程在appDemo的index页面有步骤。 

    实例代码下载:oauth2_appdemo

    OAuth 2 开发人员指南(Spring security oauth2)

     安全  OAuth 2 开发人员指南(Spring security oauth2)已关闭评论
    5月 312016
     

    OAuth 2 开发人员指南(Spring security oauth2)

    英文原文:OAuth 2 Developers Guide(spring security oauth2)

    好文章分享, 来自:http://www.oschina.net/translate/oauth-2-developers-guide

    入门

    这是支持OAuth2.0的用户指南。对于OAuth1.0,一切都是不同的,所以看它的用户指南

    本用户指南分为两个部分,第一部分是OAuth2.0提供端(OAuth 2.0 Provider),第二部分是OAuth2.0的客户端(OAuth 2.0 Client)

    OAuth2.0提供端

    OAuth2.0的提供端的用途是负责将受保护的资源暴露出去。配置包括建立一个可以访问受保护的资源的客户端代表。提供端是通过管理和验证可用于访问受保护的资源的OAuth 2令牌来做的。在适当的地方,提供端也必须为用户提供一个用于确认客户端 是否能够访问受保护的资源的接口(也就是一个页面或是一个窗口)。


    在 OAuth 2 提供者其实是分成授权服务和资源服务两个角色的,而这两个角色有时是存在于同一个应用程序中的,通过Spring Security OAuth 你可以有选择的将它们分裂到两个应用程序中,也可以有选择的给授权服务配置多个资源服务。获取令牌(Tokens)的请求是由Spring MVC的控制器端点来处理的,访问受保护的资源是通过标准的Spring Security请求过滤器来处理的。

    下面列举的端点是 Spring Security 过滤器链实现 OAuth 2 授权服务器必须的端点:

    • AuthorizationEndpoint  是用于授权服务请求的。默认的URL是:/oauth/authrize。

    • TokenEndpoint  是用于获取访问令牌(Access Tokens)的请求。默认的URL是:/oauth/token。

    下面过滤器是实现一个OAuth2资源服务器所必须的:

    • OAuth2AuthenticationProcessingFilter 这个过滤器是用于加载请求提供的一个授权了的访问令牌是否有效。

    对于所有的OAuth 2.0的提供端,通过使用Spring OAuth专门的@Configuration适配器来简化配置。也可以通过XML命名空间来配置OAuth,XML的schema存在:http://www.springframework.org/schema/security/spring-security-oauth2.xsd。命令空间是http://www.springframework.org/schema/security/oauth2

    授权服务器配置

    配置授权服务器时,您必须考虑的grant类型,从终端用户那,客户端会使用获取到的访问令牌(如授权代码、用户凭证、刷新令牌)。服务器的配置是用于提供一些实现,像客户端细节服务和令牌服务还有启用或禁用某些方面的全球机制。但是请注意,每个客户端可以专门配置权限能够使用某些授权机制和访问授权。即仅仅因为您的提供者配置为支持“客户证书”grant类型,并不意味着一个特定的客户端被授权使用grant类型。

    @EnableAuthorizationServer 注释用于配置 OAuth 2.0 授权服务器机制,加上任意一个@Beans 去实现 AuthorizationServerConfigurer (这是一个hander适配器实现的空方法)。以下功能委托给由 spring 创造的独立 configurers 而且传递到 AuthorizationServerConfigurer:

    • ClientDetailsServiceConfigurer:这个configurer定义了客户端细节服务。客户详细信息可以被初始化,或者你可以参考现有的商店。

    • AuthorizationServerSecurityConfigurer:在令牌端点上定义了安全约束。

    • AuthorizationServerEndpointsConfigurer:定义了授权和令牌端点和令牌服务


    提供端配置中重要的一项是提供给OAuth 客户端的授权码。 OAuth 客户端通过将终端用户导向一个可以输入证书/口令的授权验证页面来获取授权码,然后,将授权码传递给提供端授权服务器,服务器验证后重定向页面。 在 OAuth 2 说明文档中有详细的示例。

    在 xml 配置文件中,可以使用<authorization-server/>节点配置 OAuth 2.0 授权服务器。


    配置客户端详细步骤

    ClientDetailsServiceConfigurer 类(AuthorizationServerConfigurer类中的一个调用类)可以用来定义一个基于内存的或者JDBC的客户端信息服务。 

    客户端对象重要的属性有:

    • clientId:(必须)客户端id。

    • secret:(对于可信任的客户端是必须的)客户端的私密信息。

    • scope:客户端的作用域。如果scope未定义或者为空(默认值),则客户端作用域不受限制。

    • authorizedGrantTypes:授权给客户端使用的权限类型。默认值为空。

    • authorities:授权给客户端的权限(Spring普通的安全权限)。

    在运行的应用中,可以通过直接访问隐藏的存储文件(如:JdbcClientDetailsService中用到的数据库表)或者通过实现ClientDetailsManager 接口(也可以实现ClientDetailsService 接口,或者实现两个接口)来更新客户端信息。


    管理令牌

    AuthorizationServerTokenServices 接口里定义了 OAuth 2.0 令牌的操作方法。 注意以下几点:

    • 创建一个访问令牌时,必须保存权限信息,这样后续令牌才可以引用它。

    • 访问令牌用于加载创建令牌时的授权信息。

    创建AuthorizationServerTokenServices 接口的实现类时,你可以考虑使用DefaultTokenServices 类,它使用随机值创建令牌,并处理除永久令牌以外的所有令牌,对于永久令牌,它委托TokenStore类进行处理。 令牌默认采用基于内存实现的存储方式,但也有一些其它的存储方式。 下面是其中一些方式的简介:

    • 默认的InMemoryTokenStore 处理类对于单服务器场景非常适用(优点有:低阻塞,宕机时无需热切换到备份服务器)。大部分项目可以在开始时或者在开发模式下使用这种方式,这样比较容易启动一个没有其它依赖的服务器。

    • JdbcTokenStore 类是实现存储令牌的JDBC 版本,它将令牌信息保存到关系型数据库中。 如果服务器间共享数据库或者同一个服务器有多个实例或者授权服务器、资源服务器有多个组件,那么可以使用JDBC方式存储令牌。 使用JdbcTokenStore 类时,需要将spring-jdbc组件jar包添加到工程的编译路径中。

    • JSON网页令牌(JWT)可以加密所有令牌授权访问的数据(因此不需要在后台存储数据,这就是JWT一个重要的优点)。 缺点是你不能方便地撤销一个已授权的令牌(因此一般它们被授权的有效期较短,撤销授权的操作在刷新令牌中进行)。 另一个缺点是存储的令牌数据会越来越大因为在令牌里面存储了大量的用户证书信息。 JwtTokenStore 类不是一个真正的存储类,它未持久化(保存)任何数据,但是它在传输令牌信息和授权信息(在DefaultTokenServices类中实现)中扮演了同样的角色。 JwtTokenStore(接口)类依赖JwtAccessTokenConverter类,授权服务器和资源服务器都需要接口的实现类(因此他们可以安全地使用相同的数据并进行解码)。 令牌以默认方式进行签名,资源服务器为了能够验证这些签名,它需要有与授权服务器相同的对称密钥(服务器共享对称密钥),或者它需要有可以匹配签名私钥的公钥(公有私有密钥或混合密钥)。 为了使用JwtTokenStore 类,你需要在工程编译路径下添加spring-security-jwt组件jar包(你可以在Spring OAuthgithub资源库中找到,但是两者的版本号是不一致的)。


    Grant 类型

    AuthorizationEndpoint 通过 AuthorizationServerEndpointsConfigurer 可以配置支持 Grant 类型。默认情况下支持所有的 grant 类型,除了密码(有关详细信息,请参阅下面的信息如何开启和关闭)。以下属性影响grant类型:
        • authenticationManager:密码授予被注入一个authenticationManager开启。
        • authorizationCodeServices:为了身份验证代码授予定义了授权代码服务(org.springframework.security.oauth2.provider.code.AuthorizationCodeServices实例).
        • implicitGrantService:在隐式授予管理状态。
        • tokenGranter:TokenGranter(完全掌控的授予和忽略上面的其他属性)
在XML grant类型包括authorization-server的子元素。


    配置端点的URL

    AuthorizationServerEndpointsConfigurer有一个pathMapping()方法。该方法有两个参数:

    • defaultPath 默认的端点URL

    • customPath 自定义的URL 

    框架自己提供的URL路径是/oauth/authorize(授权端),/oauth/token (令牌端),/oauth/confirm_access (用户发送确认授权到这里),还有/oauth/error (用户呈现授权服务器授权出错的请求)。

    注意:授权端/oauth/authorize(或者是它的影射)应该是受Spring Security保护的,所以它只能被已授权的用户访问。令牌端默认是通过使用支持使用HTTP基本身份验证客户机的秘密的注解@Configuration,被Spring Oauth保护的,但不是使用XML文件的(所以在这种情况下它被保护是很明确的)。

    使用XML的<authorization-server/>元素可以使用一些属性来达到改变默认的端点URL。


    自定义错误处理

    授权服务器上错误处理使用标准的 Spring MVC 功能,即 @ExceptionHandler 端点本身的方法。用户还可以提供一个 WebResponseExceptionTranslator 端点本身,最好的办法是改变响应的内容而不是他们呈现的方式。异常的呈现代表 HttpMesssageConverters (这个可以添加到MVC的配置中)令牌的端点和OAuth的错误视图(/ OAuth /error)的授权端点。提供一个whitelabel错误端点,但是用户可能需要提供一个自定义的实现(例如,就添加一个 @Controller,它的请求映射是 @RequestMapping(“/ oauth /error”))。


    配置资源服务器

    资源服务器(可能和授权服务器或者一个单独的应用程序在同一台主机上)提供被OAuth2 令牌保护的资源。 Spring OAuth提供一个Spring Security授权过滤器,它实现保护资源的功能。在@Configuration类中,你可以使用@EnableResourceServer来开启/关闭过滤器,使用ResourceServerConfigurer来配置它。 下面是可配置的属性:

    • tokenServices:定义令牌服务的实体(ResourceServerTokenServices类的实例)。

    • resourceId:资源ID(可选的,建议配置,如果不为空,授权服务器会对它进行验证)。

    @EnableResourceServer注解把一个 OAuth2AuthenticationProcessingFilter 类型过滤器添加到Spring Security 过滤链中。

    在 XML中,有一个<resource-server/>元素,它有一个id属性 – 这是servlet过滤器的bean id,它过滤哪些可以被添加到Spring Security链中。


    配置OAuth-Aware表达式处理器

    你可能想要使用Spring Security的使用表达式语言配置访问控制的优点。 表达式处理器在 @EnableResourceServer配置中以默认方式进行注册。 表达式包括#oauth2.clientHasRole,#oauth2.clientHasAnyRole, 和 #oath2.denyClient,这些可以提供基于oauth客户端角色的访问控制(详细列表见OAuth2SecurityExpressionMethods)。 在XML中,你可以在<http/> 安全配置节点内使用expression-handler元素注册一个oauth-aware表达式处理器。

    OAuth 2.0 客户端

    OAuth 2.0 客户端控制着 OAuth 2.0保护的其它服务器的资源的访问权限。 配置包括建立相关受保护资源与有权限访问资源的用户之间的连接。 客户端也需要实现存储用户的授权代码和访问令牌的功能。


    受保护资源的配置

    受保护的资源(或称为远程资源)可以使用OAuth2ProtectedResourceDetails类型的实体bean定义。 一个受保护的资源有以下属性:

    • id:资源id。它仅在客户端搜索资源的时候使用;在OAuth协议中它从未被用到。它也被用作bean的id。

    • clientId:OAuth客户端id。OAuth提供端依赖这个id来识别客户端。

    • clientSecret:与资源有关的秘密。默认情况下,该值不为空。

    • accessTokenUri:提供访问口令的OAuth提供者终端的统一资源标识符(URI)。

    • scope:以逗号分隔的字符串列表,标识可访问资源的范围。默认情况下,该值为空。

    • clientAuthenticationScheme: 客户端对访问的令牌终端授权时使用的机制。 建议值: “http_basic” 和 “form”。 默认值: “http_basic”。 见OAuth 2 帮助文档2.1节。

    不同的授权类型有不同的实现OAuth2ProtectedResourceDetails (对于client_credentials授权类型,使用ClientCredentialsResource )的方式。对于需要进行用户身份验证的授权类型,还有一个属性:

    • userAuthorizationUri: 用户访问资源需要身份验证时跳转页面的URI。 注意这个字段不是必填的,它依赖于被支持的OAuth 2的配置文件类型。

    在XML中,可以使用<resource/>元素创建一个OAuth2ProtectedResourceDetails类型的实体bean。 它有上面提到的所有的属性。


    使用@EnableOAuth2Client对OAuth2.0的客户端的配置比较简单。主要要做两件事情:

    • 创建一个过滤bean(用oauth2ClientContextFilter)来存储当前的请求和上下文。在这种情况下需要在请求期间授权,来管理从重定向的位置和OAuth已认证的url

    • 在请求作用域中创建一个AccessTokenRequest类型的bean。这个类型的bean可以在个人用户的冲突中被识别码识别(或隐式的),授权客户端保持授权状态。

    这个过滤器需要能够连接到应用(例如,使用Servlet初始化程序或者web.xml配置文件配置 一个和DelegatingFilterProxy相同名称的代理)。


    在一个OAuth2RestTemplate中AccessTokenRequest可以这样使用:

    ?
    1
    2
    3
    4
    5
    6
    7
    @Autowired
    private OAuth2ClientContext oauth2Context;
     
    @Bean
    public OAuth2RestTemplate sparklrRestTemplate() {
        return new OAuth2RestTemplate(sparklr(), oauth2Context);
    }

    OAuth2ClientContext可以在Session的作用域中保持不同用户不同的状态。如果没有这个功能,你需要在你自己的服务强上管理等效的数据结构,映射不用用户进来的请求并且用相互隔离的OAuth2ClientContext实例连接各个用户。

    在XML文件中,有一个带有id属性的<client/>标签用于表示servlet的Filter的bean id,这个必须映射成一个和DelegatingFilterProxy有相同名称的@Configuration注解。


    访问受保护的资源

    一旦,你已经提供了所有的资源服务器配置时,现在你可以访问这些资源。建议的访问这些资源是通过使用在Spring3中提到的RestTemplate。Spring Security OAuth已经提供了一个扩展的RestTemplate,只需要提供一个OAuth2ProtectedResourceDetails的实例。使用它与user-tokens(授权代码授予)你应该考虑使用@EnableOAuth2Client配置(或XML等价< oauth:rest-template / >),造成了一些请求和会话作用域上下文对象,要求不同的用户在运行时不发生冲突。

    客户端持久化访问令牌

    客户端不需要持久化令牌,但是它可以很好的用户不需要批准一个新的令牌格兰特每次重新启动客户机应用程序。ClientTokenServices接口定义所需的操作持续OAuth 2.0为特定用户令牌。提供一个JDBC实现,但是如果你喜欢的话你可以实现自己的服务以存储的访问令牌持久数据库和相关的验证实例。如果你想使用此功能,你需要提供一个专门配置TokenProvider theOAuth2RestTemplate如

    ?
    1
    2
    3
    4
    5
    @[email protected](value = “session”, proxyMode = ScopedProxyMode.INTERFACES)public OAuth2RestOperations restTemplate() {
        OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest));
        AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider()));
        provider.setClientTokenServices(clientTokenServices());
        return template;}


    为外部 OAuth2 提供者定制客户端

    一些外部OAuth2提供商(如Facebook)不完全实现正确规范,否则他们只是困在一个旧版本比Spring Security OAuth的规范。在您的客户机应用程序使用这些供应商可能需要适应客户端基础设施的各个部分。

    使用Facebook作为一个例子,有一个Facebook功能tonr2应用程序(您需要更改配置添加你自己的,有效的,客户机id和秘密,他们很容易生成在Facebook网站上)。

    Facebook响应令牌也包含一个不一致的、有失效时间的JSON实体(他们使用到期而不是expires_in),所以如果你想在应用程序中使用失效时间你将不得不使用一个自定义OAuth2SerializationService手动解码。

    理解OAuth 2.0

     安全  理解OAuth 2.0已关闭评论
    5月 312016
     

    关于oauth2.0的文章,分享下http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

    OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。

    本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为RFC 6749

    OAuth Logo

    一、应用场景

    为了理解OAuth的适用场合,让我举一个假设的例子。

    有一个”云冲印”的网站,可以将用户储存在Google的照片,冲印出来。用户为了使用该服务,必须让”云冲印”读取自己储存在Google上的照片。

    云冲印

    问题是只有得到用户的授权,Google才会同意”云冲印”读取这些照片。那么,”云冲印”怎样获得用户的授权呢?

    传统方法是,用户将自己的Google用户名和密码,告诉”云冲印”,后者就可以读取用户的照片了。这样的做法有以下几个严重的缺点。

    (1)”云冲印”为了后续的服务,会保存用户的密码,这样很不安全。

    (2)Google不得不部署密码登录,而我们知道,单纯的密码登录并不安全。

    (3)”云冲印”拥有了获取用户储存在Google所有资料的权力,用户没法限制”云冲印”获得授权的范围和有效期。

    (4)用户只有修改密码,才能收回赋予”云冲印”的权力。但是这样做,会使得其他所有获得用户授权的第三方应用程序全部失效。

    (5)只要有一个第三方应用程序被破解,就会导致用户密码泄漏,以及所有被密码保护的数据泄漏。

    OAuth就是为了解决上面这些问题而诞生的。

    二、名词定义

    在详细讲解OAuth 2.0之前,需要了解几个专用名词。它们对读懂后面的讲解,尤其是几张图,至关重要。

    (1) Third-party application:第三方应用程序,本文中又称”客户端”(client),即上一节例子中的”云冲印”。

    (2)HTTP service:HTTP服务提供商,本文中简称”服务提供商”,即上一节例子中的Google。

    (3)Resource Owner:资源所有者,本文中又称”用户”(user)。

    (4)User Agent:用户代理,本文中就是指浏览器。

    (5)Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。

    (6)Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。

    知道了上面这些名词,就不难理解,OAuth的作用就是让”客户端”安全可控地获取”用户”的授权,与”服务商提供商”进行互动。

    三、OAuth的思路

    OAuth在”客户端”与”服务提供商”之间,设置了一个授权层(authorization layer)。”客户端”不能直接登录”服务提供商”,只能登录授权层,以此将用户与客户端区分开来。”客户端”登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。

    “客户端”登录授权层以后,”服务提供商”根据令牌的权限范围和有效期,向”客户端”开放用户储存的资料。

    四、运行流程

    OAuth 2.0的运行流程如下图,摘自RFC 6749。

    OAuth运行流程

    (A)用户打开客户端以后,客户端要求用户给予授权。

    (B)用户同意给予客户端授权。

    (C)客户端使用上一步获得的授权,向认证服务器申请令牌。

    (D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

    (E)客户端使用令牌,向资源服务器申请获取资源。

    (F)资源服务器确认令牌无误,同意向客户端开放资源。

    不难看出来,上面六个步骤之中,B是关键,即用户怎样才能给于客户端授权。有了这个授权以后,客户端就可以获取令牌,进而凭令牌获取资源。

    下面一一讲解客户端获取授权的四种模式。

    五、客户端的授权模式

    客户端必须得到用户的授权(authorization grant),才能获得令牌(access token)。OAuth 2.0定义了四种授权方式。

    • 授权码模式(authorization code)
    • 简化模式(implicit)
    • 密码模式(resource owner password credentials)
    • 客户端模式(client credentials)

    六、授权码模式

    授权码模式(authorization code)是功能最完整、流程最严密的授权模式。它的特点就是通过客户端的后台服务器,与”服务提供商”的认证服务器进行互动。

    授权码模式

    它的步骤如下:

    (A)用户访问客户端,后者将前者导向认证服务器。

    (B)用户选择是否给予客户端授权。

    (C)假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码。

    (D)客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。

    (E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。

    下面是上面这些步骤所需要的参数。

    A步骤中,客户端申请认证的URI,包含以下参数:

    • response_type:表示授权类型,必选项,此处的值固定为”code”
    • client_id:表示客户端的ID,必选项
    • redirect_uri:表示重定向URI,可选项
    • scope:表示申请的权限范围,可选项
    • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

    下面是一个例子。

    GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 Host: server.example.com

    C步骤中,服务器回应客户端的URI,包含以下参数:

    • code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
    • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

    下面是一个例子。

    HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
              &state=xyz

    D步骤中,客户端向认证服务器申请令牌的HTTP请求,包含以下参数:

    • grant_type:表示使用的授权模式,必选项,此处的值固定为”authorization_code”。
    • code:表示上一步获得的授权码,必选项。
    • redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
    • client_id:表示客户端ID,必选项。

    下面是一个例子。

    POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

    E步骤中,认证服务器发送的HTTP回复,包含以下参数:

    • access_token:表示访问令牌,必选项。
    • token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
    • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
    • refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
    • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。

    下面是一个例子。

    HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } 

    从上面代码可以看到,相关参数使用JSON格式发送(Content-Type: application/json)。此外,HTTP头信息中明确指定不得缓存。

    七、简化模式

    简化模式(implicit grant type)不通过第三方应用程序的服务器,直接在浏览器中向认证服务器申请令牌,跳过了”授权码”这个步骤,因此得名。所有步骤在浏览器中完成,令牌对访问者是可见的,且客户端不需要认证。

    简化模式

    它的步骤如下:

    (A)客户端将用户导向认证服务器。

    (B)用户决定是否给于客户端授权。

    (C)假设用户给予授权,认证服务器将用户导向客户端指定的”重定向URI”,并在URI的Hash部分包含了访问令牌。

    (D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。

    (E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。

    (F)浏览器执行上一步获得的脚本,提取出令牌。

    (G)浏览器将令牌发给客户端。

    下面是上面这些步骤所需要的参数。

    A步骤中,客户端发出的HTTP请求,包含以下参数:

    • response_type:表示授权类型,此处的值固定为”token”,必选项。
    • client_id:表示客户端的ID,必选项。
    • redirect_uri:表示重定向的URI,可选项。
    • scope:表示权限范围,可选项。
    • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

    下面是一个例子。

    GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
        Host: server.example.com

    C步骤中,认证服务器回应客户端的URI,包含以下参数:

    • access_token:表示访问令牌,必选项。
    • token_type:表示令牌类型,该值大小写不敏感,必选项。
    • expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
    • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
    • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

    下面是一个例子。

    HTTP/1.1 302 Found
         Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
                   &state=xyz&token_type=example&expires_in=3600

    在上面的例子中,认证服务器用HTTP头信息的Location栏,指定浏览器重定向的网址。注意,在这个网址的Hash部分包含了令牌。

    根据上面的D步骤,下一步浏览器会访问Location指定的网址,但是Hash部分不会发送。接下来的E步骤,服务提供商的资源服务器发送过来的代码,会提取出Hash中的令牌。

    八、密码模式

    密码模式(Resource Owner Password Credentials Grant)中,用户向客户端提供自己的用户名和密码。客户端使用这些信息,向”服务商提供商”索要授权。

    在这种模式中,用户必须把自己的密码给客户端,但是客户端不得储存密码。这通常用在用户对客户端高度信任的情况下,比如客户端是操作系统的一部分,或者由一个著名公司出品。而认证服务器只有在其他授权模式无法执行的情况下,才能考虑使用这种模式。

    密码模式

    它的步骤如下:

    (A)用户向客户端提供用户名和密码。

    (B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

    (C)认证服务器确认无误后,向客户端提供访问令牌。

    B步骤中,客户端发出的HTTP请求,包含以下参数:

    • grant_type:表示授权类型,此处的值固定为”password”,必选项。
    • username:表示用户名,必选项。
    • password:表示用户的密码,必选项。
    • scope:表示权限范围,可选项。

    下面是一个例子。

    POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded
    
         grant_type=password&username=johndoe&password=A3ddj3w

    C步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。

    HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" } 

    上面代码中,各个参数的含义参见《授权码模式》一节。

    整个过程中,客户端不得保存用户的密码。

    九、客户端模式

    客户端模式(Client Credentials Grant)指客户端以自己的名义,而不是以用户的名义,向”服务提供商”进行认证。严格地说,客户端模式并不属于OAuth框架所要解决的问题。在这种模式中,用户直接向客户端注册,客户端以自己的名义要求”服务提供商”提供服务,其实不存在授权问题。

    客户端模式

    它的步骤如下:

    (A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

    (B)认证服务器确认无误后,向客户端提供访问令牌。

    A步骤中,客户端发出的HTTP请求,包含以下参数:

    • granttype:表示授权类型,此处的值固定为”clientcredentials”,必选项。
    • scope:表示权限范围,可选项。
    POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded
    
         grant_type=client_credentials

    认证服务器必须以某种方式,验证客户端身份。

    B步骤中,认证服务器向客户端发送访问令牌,下面是一个例子。

    HTTP/1.1 200 OK
         Content-Type: application/json;charset=UTF-8
         Cache-Control: no-store
         Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" } 

    上面代码中,各个参数的含义参见《授权码模式》一节。

    十、更新令牌

    如果用户访问的时候,客户端的”访问令牌”已经过期,则需要使用”更新令牌”申请一个新的访问令牌。

    客户端发出更新令牌的HTTP请求,包含以下参数:

    • granttype:表示使用的授权模式,此处的值固定为”refreshtoken”,必选项。
    • refresh_token:表示早前收到的更新令牌,必选项。
    • scope:表示申请的授权范围,不可以超出上一次申请的范围,如果省略该参数,则表示与上一次一致。

    下面是一个例子。

    POST /token HTTP/1.1
         Host: server.example.com
         Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
         Content-Type: application/x-www-form-urlencoded
    
         grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

    openssl 生成自签名证书

     加解密, 安全  openssl 生成自签名证书已关闭评论
    6月 162015
     

    好文章一起分享下:http://www.gaojinbo.com/openssl-%E7%94%9F%E6%88%90%E8%87%AA%E7%AD%BE%E8%AF%81%E4%B9%A6.html

    要生成证书的目录下建立几个文件和文件夹,有./demoCA/ ./demoCA/newcerts/  ./demoCA/index.txt ./demoCA/serial,在serial文件中写入第一个序列号“01”

    1.生成X509格式的CA自签名证书 
    $openssl req -new -x509 -keyout ca.key -out ca.crt

     

    2.生成服务端的私钥(key文件)及csr 文件 
    $openssl genrsa -des3 -out server.key 1024 
    $openssl req -new -key server.key -out server.csr

     

    3.生成客户端的私钥(key文件)及csr文件 
    $openssl genrsa -des3 -out client.key 1024 
    $openssl req -new -key client.key -out client.csr

     

    4.用生成的CA的证书为刚才生成的server.csr,client.csr文件签名 
    $openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key 
    $openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

     

    5. 生成p12格式证书 
    $openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx 
    $openssl pkcs12 -export -inkey server.key -in server.crt -out server.pfx

     

    6.生成pem格式证书 
    有时需要用到pem格式的证书,可以用以下方式合并证书文件(crt)和私钥文件(key)来生成 
    $cat client.crt client.key> client.pem 
    $cat server.crt server.key > server.pem

     

    7.PFX文件转换为X509证书文件和RSA密钥文件 
    $openssl pkcs12 -in server.pfx -nodes -out server.pem 
    $openssl rsa -in server.pem -out server2.key 
    $openssl x509 -in server.pem -out server2.crt

     

    这样生成服务端证书:ca.crt, server.key, server.crt, server.pem, server.pfx,客户端证书:ca.crt, client.key, client.crt, client.pem, client.pfx

    TOMCAT使用BKS类型证书问题解决

     安全  TOMCAT使用BKS类型证书问题解决已关闭评论
    6月 282013
     

    转自:http://java4.blog.163.com/blog/static/7825147201172112512496/

    1.下载 BouncyCastle   http://www.bouncycastle.org/latest_releases.html

    2.把下载的JAR包拷到LIB库: bcprov-jdk16-146.jar     C:jre6libext     C:jdk1.6.0_23jrelibext   , 由于JAVA_HOME 与IDE用的JRE 有可能为两个路径,要两个都拷入

    3.修改 jrelibsecurity  下  java.security 文件 添加  security.provider.3=org.bouncycastle.jce.provider.BouncyCastleProvider    序号为方法调用顺序,可自定我定的是3。(同样修改JDK与JRE下两个文件)

    4.环境变量下的 PATH 已加入 JDK或JRE 下BIN,可在CMD中执行 keytool,

    执行:keytool -genkey -alias tomcat -storetype BKS  -keyalg RSA -keystore c:wstomcat.keystore.bks -validity 36500  

    相关解译见另一文章。如果没有 -storetype BKS  参数 默认为 JKS 类型,指定为BKS后 调用 org.bouncycastle.jce.provider.BouncyCastleProvider   进行证书生成

    5.修改TOMCAT  server.xml  去除 8443 端口注释,开放SSL功能。但要添加证书类型指定 如:

    <Connector SSLEnabled="true" clientAuth="false" keystoreFile="c:tomcat6tomcat.keystore.bks" keystoreType="BKS" keystorePass="123456" maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS"/>

    原来XML没有类型指定默认为 JKS方式,如果不写启动TOMCAT时会报  java.io.IOException: Invalid keystore format 异常

     Posted by at 上午11:31  Tagged with:

    HttpClient 如何忽略证书验证访问https – ALLOW_ALL_HOSTNAME_VERIFIER

     安全  HttpClient 如何忽略证书验证访问https – ALLOW_ALL_HOSTNAME_VERIFIER已关闭评论
    6月 272013
     

    HttpClient 如何忽略证书验证 – ALLOW_ALL_HOSTNAME_VERIFIER

     

    1。设置可以访问HTTPS

     

    Function – getNewHttpClient 

     

     

    Java代码  收藏代码

    1. /**  
    2.     * @Title: getNewHttpClient  
    3.     * @Description: Methods Description 
    4.     * @param @return     
    5.     * @return HttpClient  
    6.     * @throws  
    7.     */   
    8.       
    9.     private HttpClient getNewHttpClient() {  
    10.         try {  
    11.             KeyStore trustStore = KeyStore.getInstance(KeyStore  
    12.                     .getDefaultType());  
    13.             trustStore.load(nullnull);  
    14.             SSLSocketFactory sf = new SSLSocketFactory(trustStore);  
    15.             sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);  
    16.             HttpParams params = new BasicHttpParams();  
    17.             HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);  
    18.             HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);  
    19.             SchemeRegistry registry = new SchemeRegistry();  
    20.             registry.register(new Scheme("http", PlainSocketFactory  
    21.                     .getSocketFactory(), 80));  
    22.             registry.register(new Scheme("https", sf, 443));  
    23.             ClientConnectionManager ccm = new ThreadSafeClientConnManager(  
    24.                     params, registry);  
    25.             return new DefaultHttpClient(ccm, params);  
    26.         } catch (Exception e) {  
    27.             return new DefaultHttpClient();  
    28.         }  
    29.     }  

     

    2.忽略证书验证 

     

    Class: SSLSocketFactory

     

     

    Java代码  收藏代码

    1. import java.io.IOException;  
    2. import java.net.Socket;  
    3. import java.net.UnknownHostException;  
    4. import java.security.KeyManagementException;  
    5. import java.security.KeyStore;  
    6. import java.security.KeyStoreException;  
    7. import java.security.NoSuchAlgorithmException;  
    8. import java.security.UnrecoverableKeyException;  
    9. import java.security.cert.CertificateException;  
    10. import java.security.cert.X509Certificate;  
    11. import javax.net.ssl.SSLContext;  
    12. import javax.net.ssl.TrustManager;  
    13. import javax.net.ssl.X509TrustManager;  
    14. import org.apache.http.conn.ssl.SSLSocketFactory;  
    15.   
    16.   
    17. public class SSLSocketFactory extends SSLSocketFactory {  
    18.     /**  
    19.     * @Fields sslContext  
    20.     * @Description: Field Description 
    21.     */  
    22.     SSLContext sslContext = SSLContext.getInstance("TLS");  
    23.   
    24.     /**  
    25.     * <p>Title: </p>  
    26.     * <p>Description: </p>  
    27.     * @param truststore 
    28.     * @throws NoSuchAlgorithmException 
    29.     * @throws KeyManagementException 
    30.     * @throws KeyStoreException 
    31.     * @throws UnrecoverableKeyException  
    32.     */  
    33.     public SSLSocketFactory(KeyStore truststore)  
    34.             throws NoSuchAlgorithmException, KeyManagementException,  
    35.             KeyStoreException, UnrecoverableKeyException {  
    36.         super(truststore);  
    37.         TrustManager tm = new X509TrustManager() {  
    38.             public void checkClientTrusted(X509Certificate[] chain,  
    39.                     String authType) throws CertificateException {  
    40.             }  
    41.   
    42.             public void checkServerTrusted(X509Certificate[] chain,  
    43.                     String authType) throws CertificateException {  
    44.             }  
    45.   
    46.             public X509Certificate[] getAcceptedIssuers() {  
    47.                 return null;  
    48.             }  
    49.         };  
    50.         sslContext.init(nullnew TrustManager[] { tm }, null);  
    51.     }  
    52.   
    53.     /* (non-Javadoc) 
    54.     * <p>Title: createSocket</p>  
    55.     * <p>Description: </p>  
    56.     * @param socket 
    57.     * @param host 
    58.     * @param port 
    59.     * @param autoClose 
    60.     * @return 
    61.     * @throws IOException 
    62.     * @throws UnknownHostException  
    63.     * @see org.apache.http.conn.ssl.SSLSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)  
    64.     */  
    65.     @Override  
    66.     public Socket createSocket(Socket socket, String host, int port,  
    67.             boolean autoClose) throws IOException, UnknownHostException {  
    68.         return sslContext.getSocketFactory().createSocket(socket, host, port,  
    69.                 autoClose);  
    70.     }  
    71.   
    72.     /* (non-Javadoc) 
    73.     * <p>Title: createSocket</p>  
    74.     * <p>Description: </p>  
    75.     * @return 
    76.     * @throws IOException  
    77.     * @see org.apache.http.conn.ssl.SSLSocketFactory#createSocket()  
    78.     */  
    79.     @Override  
    80.     public Socket createSocket() throws IOException {  
    81.         return sslContext.getSocketFactory().createSocket();  
    82.     }  
    83. }  

     

     

    3。调用并用HTTPS访问

     

     

    Java代码  收藏代码

    1. DefaultHttpClient httpclient = (DefaultHttpClient) getNewHttpClient();  
    2.                   
    3.         try {  
    4.             //Secure Protocol implementation.    
    5.             SSLContext ctx = SSLContext.getInstance("SSL");  
    6.             //Implementation of a trust manager for X509 certificates    
    7.             X509TrustManager tm = new X509TrustManager() {  
    8.   
    9.                 public void checkClientTrusted(X509Certificate[] xcs,  
    10.                         String string) throws CertificateException {  
    11.   
    12.                 }  
    13.   
    14.                 public void checkServerTrusted(X509Certificate[] xcs,  
    15.                         String string) throws CertificateException {  
    16.                 }  
    17.   
    18.                 public X509Certificate[] getAcceptedIssuers() {  
    19.                     return null;  
    20.                 }  
    21.             };  
    22.             ctx.init(nullnew TrustManager[] { tm }, null);  
    23.             SSLSocketFactory ssf = new SSLSocketFactory(ctx);  
    24.             ClientConnectionManager ccm = httpclient.getConnectionManager();  
    25.             //register https protocol in httpclient's scheme registry    
    26.             SchemeRegistry sr = ccm.getSchemeRegistry();  
    27.             sr.register(new Scheme("https"443, ssf));  
    28.         } catch (Exception e) {  
    29.             e.printStackTrace();  
    30.         }  
    31.   
    32.         HttpGet httpGet = new HttpGet(httpGetUrl);  
    33.         HttpResponse response = httpclient.execute(httpGet, localContext);  

     

     

     Posted by at 下午6:14  Tagged with:

    OAUTH协议简介

     安全  OAUTH协议简介已关闭评论
    6月 182013
     

       摘要:OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同时,任何第三方都可以使用OAUTH认证服务,任何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间,因而OAUTH是简易的。目前互联网很多服务如Open API,很多大头公司如Google,Yahoo,Microsoft等都提供了OAUTH认证服务,这些都足以说明OAUTH标准逐渐成为开放资源授权的标准。

    一、OAUTH产生的背景

        典型案例:如果一个用户拥有两项服务:一项服务是图片在线存储服务A,另一个是图片在线打印服务B。如下图所示。由于服务A与服务B是由两家不同的服务提供商提供的,所以用户在这两家服务提供商的网站上各自注册了两个用户,假设这两个用户名各不相同,密码也各不相同。当用户要使用服务B打印存储在服务A上的图片时,用户该如何处理?法一:用户可能先将待打印的图片从服务A上下载下来并上传到服务B上打印,这种方式安全但处理比较繁琐,效率低下;法二:用户将在服务A上注册的用户名与密码提供给服务B,服务B使用用户的帐号再去服务A处下载待打印的图片,这种方式效率是提高了,但是安全性大大降低了,服务B可以使用用户的用户名与密码去服务A上查看甚至篡改用户的资源。

        很多公司和个人都尝试解决这类问题,包括Google、Yahoo、Microsoft,这也促使OAUTH项目组的产生。OAuth是由Blaine Cook、Chris Messina、Larry Halff 及David Recordon共同发起的,目的在于为API访问授权提供一个开放的标准。OAuth规范的1.0版于2007年12月4日发布。通过官方网址:http://oauth.net可以阅读更多的相关信息。

    二、OAUTH简介

        在官方网站的首页,可以看到下面这段简介:

        An open protocol to allow secure API authorization in a simple and standard method from desktop and web applications.

     

        大概意思是说OAUTH是一种开放的协议,为桌面程序或者基于BS的web应用提供了一种简单的,标准的方式去访问需要用户授权的API服务。OAUTH类似于Flickr Auth、Google's AuthSub、Yahoo's BBAuth、 Facebook Auth等。OAUTH认证授权具有以下特点:

    1. 简单:不管是OAUTH服务提供者还是应用开发者,都很容易于理解与使用;

    2. 安全:没有涉及到用户密钥等信息,更安全更灵活;

    3. 开放:任何服务提供商都可以实现OAUTH,任何软件开发商都可以使用OAUTH;

     三、OAUTH相关术语

        在弄清楚OAUTH流程之前,我们先了解下OAUTH的一些术语的定义:

    • OAUTH相关的三个URL

      • Request Token URL: 获取未授权的Request Token服务地址;
      • User Authorization URL: 获取用户授权的Request Token服务地址;
      • Access Token URL: 用授权的Request Token换取Access Token的服务地址;

     

    • OAUTH相关的参数定义:

      • oauth_consumer_key: 使用者的ID,OAUTH服务的直接使用者是开发者开发出来的应用。所以该参数值的获取一般是要去OAUTH服务提供商处注册一个应用,再获取该应用的oauth_consumer_key。如Yahoo该值的注册地址为:https://developer.yahoo.com/dashboard/
      • oauth_consumer_secret:oauth_consumer_key对应的密钥。
      • oauth_signature_method: 请求串的签名方法,应用每次向OAUTH三个服务地址发送请求时,必须对请求进行签名。签名的方法有:HMAC-SHA1、RSA-SHA1与PLAINTEXT等三种。
      • oauth_signature: 用上面的签名方法对请求的签名。
      • oauth_timestamp: 发起请求的时间戳,其值是距1970 00:00:00 GMT的秒数,必须是大于0的整数。本次请求的时间戳必须大于或者等于上次的时间戳。
      • oauth_nonce: 随机生成的字符串,用于防止请求的重放,防止外界的非法攻击。
      • oauth_version: OAUTH的版本号,可选,其值必须为1.0。

      OAUTH HTTP响应代码:

    • HTTP 400 Bad Request 请求错误

      • Unsupported parameter 参数错误
      • Unsupported signature method 签名方法错误
      • Missing required parameter 参数丢失
      • Duplicated OAuth Protocol Parameter 参数重复
    • HTTP 401 Unauthorized 未授权

      • Invalid Consumer Key 非法key
      • Invalid / expired Token 失效或者非法的token
      • Invalid signature 签名非法
      • Invalid / used nonce 非法的nonce

    四、OAUTH认证授权流程

        在弄清楚了OAUTH的术语后,我们可以对OAUTH认证授权的流程进行初步认识。其实,简单的来说,OAUTH认证授权就三个步骤,三句话可以概括:

    1. 获取未授权的Request Token

    2. 获取用户授权的Request Token

    3. 用授权的Request Token换取Access Token

        当应用拿到Access Token后,就可以有权访问用户授权的资源了。大家肯能看出来了,这三个步骤不就是对应OAUTH的三个URL服务地址嘛。一点没错,上面的三个步骤中,每个步骤分别请求一个URL,并且收到相关信息,并且拿到上步的相关信息去请求接下来的URL直到拿到Access Token。具体的步骤如下图所示:

     

    具体每步执行信息如下:

    A. 使用者(第三方软件)向OAUTH服务提供商请求未授权的Request Token。向Request Token URL发起请求,请求需要带上的参数见上图。

    B. OAUTH服务提供商同意使用者的请求,并向其颁发未经用户授权的oauth_token与对应的oauth_token_secret,并返回给使用者。

    C. 使用者向OAUTH服务提供商请求用户授权的Request Token。向User Authorization URL发起请求,请求带上上步拿到的未授权的token与其密钥。

    D. OAUTH服务提供商将引导用户授权。该过程可能会提示用户,你想将哪些受保护的资源授权给该应用。此步可能会返回授权的Request Token也可能不返回。如Yahoo OAUTH就不会返回任何信息给使用者。

    E. Request Token 授权后,使用者将向Access Token URL发起请求,将上步授权的Request Token换取成Access Token。请求的参数见上图,这个比第一步A多了一个参数就是Request Token。

    F. OAUTH服务提供商同意使用者的请求,并向其颁发Access Token与对应的密钥,并返回给使用者。

    G. 使用者以后就可以使用上步返回的Access Token访问用户授权的资源。

        从上面的步骤可以看出,用户始终没有将其用户名与密码等信息提供给使用者(第三方软件),从而更安全。用OAUTH实现背景一节中的典型案例:当服务B(打印服务)要访问用户的服务A(图片服务)时,通过OAUTH机制,服务B向服务A请求未经用户授权的Request Token后,服务A将引导用户在服务A的网站上登录,并询问用户是否将图片服务授权给服务B。用户同意后,服务B就可以访问用户在服务A上的图片服务。整个过程服务B没有触及到用户在服务A的帐号信息。如下图所示,图中的字母对应OAUTH流程中的字母:

     

    五、OAUTH服务提供商

        OAUTH标准提出到现在不到两年,但取得了很大成功。不仅提供了各种语言的版本库,甚至Google,Yahoo,Microsoft等等互联网大头都实现了OAUTH协议。由于OAUTH的client包有很多,所以我们就没有必要在去自己写,避免重复造轮子,直接拿过来用就行了。我使用了这些库去访问Yahoo OAUTH服务,很不错哦!下面就贴出一些图片跟大家一起分享下!

        下图是OAUTH服务提供商引导用户登录(若用户开始没有登录)

       

        下图是提示用户将要授权给第三方应用,是否同意授权的页面

     

        下图提示用户已授权成功的信息

     

        一些服务提供商不仅仅仅实现了OAUTH协议上的功能,还提供了一些更友好的服务,比如管理第三方软件的授权服务。下图就是YAHOO管理软件授权的页面,用户可以取消都某些应用的授权。

     

     

     Posted by at 上午10:59  Tagged with: