Spring security oauth2最简单入门环境搭建--二、干货

标签: spring security oauth2 | 发表时间:2015-07-26 00:59 | 作者:
出处:http://www.iteye.com
关于OAuth2的一些简介,见我的上篇blog: http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉。。

友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页。

我有信心我的这个blog应该是迄今为止使用spring security oauth2最简单的hello world app介绍了,如果你 下下来附件源码还看不懂,请留言。。

其他能搜到的如 http://blog.csdn.net/monkeyking1987/article/details/16828059这个哥们儿

http://www.cnblogs.com/smarterplanet/p/4088479.html
这个,都很好,不过因为依赖了数据库,配置比较多,对于初学者来说,搭起来一个最最简单的环境才是最重要的,撸要一步一步走嘛(如果对spring不是特别熟,强烈 不建议看官方的tutorial,槽点太多,例如静态JS库的引用方式,web.xml的使用方式,Spring的配置方式,我反正下下来就惊呆了,第一次看到用java代码配spring)

基本需求:
用户A希望授权网站B能获取自己在网站appDemo的一个资源,资源的地址是
http://localhost:8080/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配置:
  • <authentication-manager id="clientAuthenticationManager">
    		<authentication-provider user-service-ref="oauth2ClientDetailsUserService" />
    	</authentication-manager>
    	<beans:bean id="oauth2ClientDetailsUserService"
    	class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
    		<beans:constructor-arg ref="clientDetailsService" />
    	</beans:bean>
    <oauth2:client-details-service id="clientDetailsService">
    		<oauth2:client client-id="m1"
    			authorized-grant-types="password,authorization_code,refresh_token,implicit"
    			secret="s1" scope="read,write,trust" authorities="ROLE_CLIENT, ROLE_TRUSTED_CLIENT"
    			resource-ids="pic-resource" />
    	</oauth2:client-details-service>

    注意命名空间,可以看到client配置和spring security传统的用户配置是非常像的。
    这里配置了网站B在appDemo中的client_id,client_secret,scope,权限和授权类型,资源ID,那这个资源ID是个啥呢?
  • 资源filter配置:
  • <oauth2:resource-server id="picResourceServer"
    		resource-id="pic-resource" token-services-ref="tokenServices" />

    配置这个,除了资源定位(id),还为了给我们的资源加上一个自定义的OAuth过滤器,这个过滤器主要是为了网站B在访问资源的时候验证Access Token。然后出现了两个分支:
    1.配token service
    2.配资源
  • 先讲Token配置:
  • <beans:bean id="tokenServices"
    		class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
    		<beans:property name="tokenStore" ref="tokenStore" />
    		<beans:property name="supportRefreshToken" value="true" />
    		<beans:property name="clientDetailsService" ref="clientDetailsService" />
    	</beans:bean>
    	<beans:bean id="tokenStore"
    		class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore">
    	</beans:bean>

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

  • 资源和资源的保护
  • <http pattern="/resource/**" create-session="never"
    		entry-point-ref="oauth2AuthenticationEntryPoint"
    		access-decision-manager-ref="oauth2AccessDecisionManager">
    		<anonymous enabled="false" />
    		<intercept-url pattern="/resource/**" access="ROLE_USER,SCOPE_READ" />
    		<custom-filter ref="picResourceServer" before="PRE_AUTH_FILTER" />
    		<access-denied-handler ref="oauthAccessDeniedHandler" />
    	</http>

    这是spring security的传统配置了,除了我们刚才提到的资源filter,还配置了认证失败、授权失败的处理,和判断是否可访问的"access decision manager"
  • 认证失败,授权失败
  • <beans:bean id="oauth2AuthenticationEntryPoint"
    		class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint" />
    
    	<beans:bean id="oauthAccessDeniedHandler"
    		class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

    这个没什么好解释的了,其实作为demo也可以不配,毕竟我们应该会一路按能跑通的先跑。
  • access decision manager
  • <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里面特有的scope投票机制。

    好,到现在为止,OAuth2 Server所需要的所有龙珠都已经集齐,接下来就可以召唤神龙了
  • 出来吧!神龙
  • <oauth2:authorization-server
    		client-details-service-ref="clientDetailsService" token-services-ref="tokenServices"
    		user-approval-handler-ref="oauthUserApprovalHandler"
    		user-approval-page="oauth_approval" error-page="oauth_error">
    		<oauth2:authorization-code />
    		<oauth2:implicit />
    		<oauth2:refresh-token />
    		<oauth2:client-credentials />
    		<oauth2:password />
    	</oauth2:authorization-server>
    
    	<beans:bean id="oauthUserApprovalHandler"
    		class="org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler" />


    还差两步:
    1.网站B来申请Token时候的认证和权限设置:
    <http pattern="/oauth/token" create-session="stateless"
    		authentication-manager-ref="clientAuthenticationManager"
    		entry-point-ref="oauth2AuthenticationEntryPoint">
    		<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
    		<anonymous enabled="false" />
    		<http-basic entry-point-ref="oauth2AuthenticationEntryPoint" />
    		<custom-filter ref="clientCredentialsTokenEndpointFilter"
    			before="BASIC_AUTH_FILTER" />
    		<access-denied-handler ref="oauthAccessDeniedHandler" />
    	</http>
    
    	<beans:bean id="clientCredentialsTokenEndpointFilter"
    		class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    		<beans:property name="authenticationManager" ref="clientAuthenticationManager" />
    	</beans:bean>


    2.作为屌丝用户A,认证放在配置最后了(也应该放在前面那个http的后面,因为这里有个全局匹配了)
    <http access-denied-page="/login.jsp?error=true"
    		authentication-manager-ref="authenticationManager">
    		<intercept-url pattern="/oauth/**" access="ROLE_USER" />
    		<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    		<form-login login-page="/login.jsp"
    			authentication-failure-url="/login.jsp?error=true"
    			default-target-url="/index.jsp" />
    		<anonymous />
    	</http>
    
    	<authentication-manager alias="authenticationManager">
    		<authentication-provider>
    			<user-service id="userService">
    				<user name="admin" password="admin" authorities="ROLE_USER" />
    			</user-service>
    		</authentication-provider>
    	</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页面有步骤。

    完。



    已有 0 人发表留言,猛击->> 这里<<-参与讨论


    ITeye推荐



    相关 [spring security oauth2] 推荐:

    Spring security oauth2最简单入门环境搭建--二、干货

    - - ITeye博客
    关于OAuth2的一些简介,见我的上篇blog: http://wwwcomy.iteye.com/blog/2229889 PS:貌似内容太水直接被鹳狸猿干沉. 友情提示 学习曲线:spring+spring mvc+spring security+Oauth2基本姿势,如果前面都没看过请及时关闭本网页.

    使用Spring Security Oauth2完成RESTful服务password认证的过程 - 王安琪

    - - 博客园_首页
            摘要:Spring Security与Oauth2整合步骤中详细描述了使用过程,但它对于入门者有些重量级,比如将用户信息、ClientDetails、token存入数据库而非内存. 配置过程比较复杂,经过几天时间试验终于成功,下面我将具体的使用Spring Security Oauth2完成password认证的过程记录下来与大家分享.

    cxf + spring 的WS Security示例

    - - RSS - IT博客云
    WSPasswordCallback的 passwordType属性和 password属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到 password属性,WSS4J会自动比较客户端传来的值和你设置的这个值. 你可能会问为什么这里CXF不把客户端提交的密码传入让我们在 ServerPasswordCallbackHandler中比较呢.

    Spring Boot 使用Spring security 集成CAS - CSDN博客

    - -
          创建Maven工程:springboot-security-cas.       创建工程后,打开pom.xml,在pom.xml中加入以下内容:.           .           . 3.创建application.properties.

    奔的家园 | CAS 与 Spring Security 3.1整合配置详解

    - - Delicious/searchfull
    该方式通过获取CAS系统里的角色,来支持CAS与Spring Security的关联,注意该文章authorities部分. 一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分. 用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统.

    spring security 3.1.0 控制用户重复登陆

    - - CSDN博客架构设计推荐文章
    通过配置我们可以实现两个需求 1、限制不允许第二个用户登录,2、第二个登陆用户踢掉前一个登陆用户 . 假设你的spring架构已经可以使用了(其他的主要功能完成),需要增加登录限制功能. 注:这里只写配置不写原理(不懂的就问度娘),其实个人认为先配置好跑起来再研究下原理最好了. 通过sessionRegistry可以获取系统当前在线人数和登录用户信息.

    spring security 3中推荐使用BCrypt算法加密密码

    - - jackyrong
    spring security 3中推荐使用BCrypt算法加密密码了,以前使用的是md5,. Md5PasswordEncoder 和 ShaPasswordEncoder,现在不推荐了,推荐用bcrpt. Bcrpt中的salt可以是随机的,比如:.   其中strenth为长度. 已有 0 人发表留言,猛击->> 这里<<-参与讨论.

    Spring Security判断用户是否已经登录 - 简书

    - -
    方法一、JSP中检查user principal. 需要:.

    spring security中限制用户登录次数超过限制的处理

    - - ITeye博客
    在登录的时候,往往希望记录如果登录失败者的ip,并且登录失败次数超过一定的,则不给登录,予以封锁. 在spring security中,可以通过如下方式实现. 1) 实现AuthenticationFailureEventListener,这个监听器用来监听. 2) 同样有登录成功的监听. 3) LoginAttemptService中,主要是通过缓存记录登录失败次数等,十分简单.

    (收藏)Spring Security笔记:解决CsrfFilter与Rest服务Post方式的矛盾

    - - jackyrong
    基于Spring Security+Spring MVC的web应用,为了防止跨站提交攻击,通常会配置csrf,即:. 如果应用中有Post方式访问的Rest服务(参考下面的代码),会很不幸的发现,所有POST方式请求的服务会调用失败. 原因在于:启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher.