参考以下两个文章:

http://www.cnblogs.com/0201zcr/p/5328847.html

http://wwwcomy.iteye.com/blog/2230265

web.xml 注意这里的<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>   <url-pattern>/*</url-pattern>  而<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    <url-pattern>*.action</url-pattern>会导致org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter构造器里面的/oauth/token被security拦截,而spring mvc却没有拦截

    <!-- SpringSecurity必须的filter start-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- SpringSecurity必须的filter end--> <servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContextMvc.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
    <!--  /oauth/token 是oauth2登陆验证请求的url     用于获取access_token  ,默认的生存时间是43200秒,即12小时-->
<http pattern="/oauth/token.action" create-session="stateless" authentication-manager-ref="clientAuthenticationManager">
<intercept-url pattern="/oauth/token.action" access="IS_AUTHENTICATED_FULLY" /> <!-- 可以访问的角色名称,如果需要拦截,需要实现UserDetails接口,实现getAuthorities()方法-->
<anonymous enabled="false" />
<http-basic entry-point-ref="oauth2AuthenticationEntryPoint" />
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauth2AccessDeniedHandler" />
</http>

这个authentication-manager 是OAUTH的,还需要另一个spring security ,如果已经在使用spring security 那么只需要配置这一个.ClientDetailsUserDetailsService 实现了spring security的UserDetailsService,在ClientDetailsUserDetailsService

的loadUserByUsername并不是验证我们用户的账号密码,验证用户的账号密码在spring security里面已经自己处理了,这里的loadUserByUsername是验证我们的客户端也就是第三方的网址,或者APP,是否有权限访问我们的接口.例如这里我们的第三方APP用户名为mobile_1,密码为secret_1,可以配置多个第三方APP

        <!-- 验证的权限控制 -->
<authentication-manager id="clientAuthenticationManager">
<authentication-provider user-service-ref="oauth2ClientDetailsUserService" />
</authentication-manager> <oauth2:client-details-service id="clientDetailsService" >
<oauth2:client client-id="mobile_1" authorized-grant-types="password,authorization_code,refresh_token,implicit" secret="secret_1" scope="read,write,trust" authorities="ROLE_CLIENT,ROLE_TRUSTED_CLIENT" resource-ids="mobile-resource" />
</oauth2:client-details-service>
<beans:bean id="oauth2ClientDetailsUserService" class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<beans:constructor-arg ref="clientDetailsService" />
</beans:bean>

spring security 的authentication-manager  , daoAuthenticationProvider需要自己实现,这里就不贴出来了

      <!-- 权限管理者 -->
<authentication-manager alias="myAuthenticationManager">
<!-- 权限提供者 -->
<authentication-provider ref="daoAuthenticationProvider" />
</authentication-manager> <beans:bean id="daoAuthenticationProvider" class="com.thesys.common.security.provider.MyDaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="securityService" />
<beans:property name="PasswordEncoder" ref="md5PasswordEncoder" />
</beans:bean>

复制org.springframework.security.oauth2.provider.token.DefaultTokenServices 内容新建类MyTokenService  自己重写 private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken)这个方法,实现自己的TOKEN生成方式

              <!-- for spring oauth2 -->
<!--token在服务器存储的方式 InMemoryTokenStore :保存在内存 ;JdbcTokenStore : 保存在数据库中 -->
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<!--<beans:bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">--> <!--令牌服务的实体-->
<beans:bean id="tokenServices" class="com.thesys.common.security.oauth.MyTokenService" >
<beans:property name="tokenStore" ref="tokenStore"></beans:property>
<beans:property name="supportRefreshToken" value="true"/>
<beans:property name="clientDetailsService" ref="clientDetailsService" />
</beans:bean> <!-- 自己重写的类 -->
<!--处理访问成功-->
<beans:bean id="oauth2AuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint" />
<!--处理访问拒绝-->
<beans:bean id="oauth2AccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<!--处理认证点-->
<beans:bean id="oauthUserApprovalHandler" class="org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler" />
<!--处理访问控制-->
<beans:bean id="oauth2AccessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
<beans:constructor-arg>
<beans:list>
<beans:bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<beans:bean class="org.springframework.security.access.vote.RoleVoter" />
<beans:bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</beans:list>
</beans:constructor-arg>
</beans:bean> <!--oauth2 的server所能支持的请求类型-->
<oauth2:authorization-server client-details-service-ref="clientDetailsService" token-services-ref="tokenServices" user-approval-handler-ref="oauthUserApprovalHandler">
<oauth2:authorization-code />
<oauth2:implicit />
<oauth2:refresh-token />
<oauth2:client-credentials />
<oauth2:password />
</oauth2:authorization-server>

这里解决.do .action的拦截问题, <beans:constructor-arg value="/oauth/token.action" /> 把默认的/oauth/token 改成/oauth/token.action 就可以解决.do或者.action 的拦截问题

 <beans:bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="clientAuthenticationManager" />
<beans:constructor-arg value="/oauth/token.action" />
</beans:bean>  
 <intercept-url pattern="/admin**" access="IS_AUTHENTICATED_FULLY" /> 因为没有项目没有角色的设置,只要登录了就可以访问,所以不设置角色验证
   <!--指定spring要保护的资源,如果没有这个,访问控制的时候会说没有Authentication object:-->
<oauth2:resource-server id="mobileResourceServer" resource-id="mobile-resource" token-services-ref="tokenServices" /> <http pattern="/json**" create-session="never" entry-point-ref="oauth2AuthenticationEntryPoint" access-decision-manager-ref="oauth2AccessDecisionManager">
<anonymous enabled="false" />
<intercept-url pattern="/json**" access="IS_AUTHENTICATED_FULLY" /><!-- -->
<custom-filter ref="mobileResourceServer" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauth2AccessDeniedHandler" />
</http> <http pattern="/admin**" create-session="never" entry-point-ref="oauth2AuthenticationEntryPoint" access-decision-manager-ref="oauth2AccessDecisionManager">
<anonymous enabled="false" />
<intercept-url pattern="/admin**" access="IS_AUTHENTICATED_FULLY" /> <!-- -->
<custom-filter ref="mobileResourceServer" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauth2AccessDeniedHandler" />
</http>

因为没有设置必须为POST 提交,所以无论GET POST 提交以下请求会返回access_token

http://localhost:8028/oauth/token.action?client_id=mobile_1&client_secret=secret_1&grant_type=password&username=test&password=1
  1. {
  2. "access_token": "6cd40d26561c4ac89e447dd5214c7033",
  3. "token_type": "bearer",
  4. "refresh_token": "459f7555-e733-43c9-8ab8-016b15a61427",
  5. "expires_in": 43199,
  6. "scope": "read trust write"
  7. }

刷新access_token

/oauth/token.action?client_id=&client_secret=&grant_type=refresh_token&refresh_token=459f7555-e733-43c9-8ab8-016b15a61427

{
"access_token": "859f08ec-7552-45b2-bb54-50328e462646",
"token_type": "bearer",
"refresh_token": "26bef8b9-2521-4efd-a81b-1e2873866c8f",
"expires_in": 2591999,
"scope": "read trust write"
}


然后带着access_token访问,就可以成功访问

http://localhost:8028/admin.action?access_token=52d33d7d81ee4a388d79bf00387b1325

没有access_token访问的话,会返回(注意看这里是XML方式返回,因为请求头为空,spring返回默认第一个,如果需要json,那么请在请求头加上accept:application/json)

http://localhost:8028/admin.action
  1. <oauth>
  2. <error_description>An Authentication object was not found in the SecurityContext</error_description>
  3. <error>unauthorized</error>
  4. </oauth>

数据库存储方式

    <!--token在服务器存储的方式    InMemoryTokenStore :保存在内存     ;JdbcTokenStore : 保存在数据库中
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />-->
<beans:bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore" >

按照规范建两个表,因为需要访问的第三方不多,我只需要持久化access_token所以没有建立oauth_client_details,oauth_code

Drop table  if exists oauth_access_token;
create table oauth_access_token (
create_time timestamp default now(),
token_id VARCHAR(255),
token BLOB,
authentication_id VARCHAR(255),
user_name VARCHAR(255),
client_id VARCHAR(255),
authentication BLOB,
refresh_token VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; Drop table if exists oauth_refresh_token;
create table oauth_refresh_token (
create_time timestamp default now(),
token_id VARCHAR(255),
token BLOB,
authentication BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

spring oauth2 ,spring security整合oauth2.0 JdbcTokenStore实现 解决url-pattern .do .action的更多相关文章

  1. Spring Boot Security 整合 OAuth2 设计安全API接口服务

    简介 OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版.本文重点讲解Spring Boot项目对OAuth2进行的实现,如果你对OAut ...

  2. Spring Boot Security 整合 JWT 实现 无状态的分布式API接口

    简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.JSON Web Token 入门教程 - 阮一峰,这篇文章可以帮你了解JWT的概念.本文重点讲解Spring Boo ...

  3. Spring Security实现OAuth2.0授权服务 - 进阶版

    <Spring Security实现OAuth2.0授权服务 - 基础版>介绍了如何使用Spring Security实现OAuth2.0授权和资源保护,但是使用的都是Spring Sec ...

  4. Spring Security实现OAuth2.0授权服务 - 基础版

    一.OAuth2.0协议 1.OAuth2.0概述 OAuth2.0是一个关于授权的开放网络协议. 该协议在第三方应用与服务提供平台之间设置了一个授权层.第三方应用需要服务资源时,并不是直接使用用户帐 ...

  5. security和oauth2.0的整合

    security和oauth2.0的整合 之前已经介绍过security的相关的介绍,现在所需要做的就是security和oauth2.0的整合,在原有的基础上我们加上一些相关的代码;代码实现如下: ...

  6. Spring Cloud实战 | 最八篇:Spring Cloud +Spring Security OAuth2+ Axios前后端分离模式下无感刷新实现JWT续期

    一. 前言 记得上一篇Spring Cloud的文章关于如何使JWT失效进行了理论结合代码实践的说明,想当然的以为那篇会是基于Spring Cloud统一认证架构系列的最终篇.但关于JWT另外还有一个 ...

  7. 使用Spring Security和OAuth2实现RESTful服务安全认证

    这篇教程是展示如何设置一个OAuth2服务来保护REST资源. 源代码下载github. (https://github.com/iainporter/oauth2-provider)你能下载这个源码 ...

  8. Spring Security +Oauth2 +Spring boot 动态定义权限

    Oauth2介绍:Oauth2是为用户资源的授权定义了一个安全.开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息,并且这是安全的. 简单的来说,当用户登陆网站的时候,需要账号 ...

  9. spring boot:spring security+oauth2+sso+jwt实现单点登录(spring boot 2.3.3)

    一,sso的用途 ? 1,如果有多个应用系统,用户只需要登录一次就可以访问所有相互信任的应用系统. 不需要每次输入用户名称和用户密码, 也不需要创建并记忆多套用户名称和用户密码. 2,系统管理员只需维 ...

随机推荐

  1. cobbler自动化安装系统

    笔者Q:972581034 交流群:605799367.有任何疑问可与笔者或加群交流 在很久很久以前,使用kickstart实现自动化安装的时候,我一直认为装系统是多么高大上的活,直到cobbler的 ...

  2. 准备:新V8即将到来,Node.js的性能正在改变

    V8的Turbofan的性能特点将如何对我们优化的方式产生影响 审阅:来自V8团队的Franziska Hinkelmann和Benedikt Meurer. **更新:Node.js 8.3.0已经 ...

  3. zookeeper 实现分布式锁

    主要是依赖临时节点的特性.数据存储到内存中效率高:例如有web1 web2 两台应用服务器 db1 db2两台db服务器  db互为主备,web1 web2 分别去修改db1 .有限db2库里张三的年 ...

  4. SQL Server中计算表达式的和

    项目使用的是SQL Server数据库,需要做一个审核规则,字段A中表达式的值和字段B中的值,做比较: 需求本身很简单,但是表达式中存在很多非法字符(非法全角,运算符,汉字--) eg:1.1.1*2 ...

  5. JS对象、原型链

    忘记在哪里看到过,有人说鉴别一个人是否 js 入门的标准就是看他有没有理解 js 原型,所以第一篇总结就从这里出发. 对象 JavaScript 是一种基于对象的编程语言,但它与一般面向对象的编程语言 ...

  6. Android开发之漫漫长途 XIV——ListView

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  7. BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]

    小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如 ...

  8. typeof面试题解答

    面试题 alert(typeof null); // object alert(typeof undefined); // undefined alert(typeof NaN); // number ...

  9. HP中spl_autoload_register函数的用法

    spl_autoload_register(PHP 5 >= 5.1.2) spl_autoload_register - 注册__autoload()函数 说明bool spl_autoloa ...

  10. 开始使用PHPUnit单元测试

    何为单元测试: 指对软件中的基本单元进行测试,如函数.方法等,以检查其返回值或行为是否符合预期:实际中软件是很复杂的,由许多组件构成,执行流程连贯在一起,要进行单元片段的测试,就需要为其提供执行上下文 ...