oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架

三、简单搭建spring sercurity+oauth2.0 的框架

  1. oauth_parent:父工程
  2. oauth-authorizationServer:认证服务器
  3. oauth-ResourceServer:资源服务器

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第1张图片

oauth_parent:父工程代码(就是pom配置)

	
	
		4.0.0

		oauth-learn
		oauth-parent
		1.0-SNAPSHOT

		pom

		
			org.springframework.boot
			spring-boot-starter-parent
			2.1.3.RELEASE
		

		
			UTF-8
			UTF-8
			1.8
		

		
			

				
					org.springframework.cloud
					spring-cloud-dependencies
					Greenwich.RELEASE
					pom
					import
				


				
					javax.servlet
					javax.servlet-api
					3.1.0
					provided
				

				
					javax.interceptor
					javax.interceptor-api
					1.2
				

				
					com.alibaba
					fastjson
					1.2.47
				

				
					org.projectlombok
					lombok
					1.18.0
				



				
					org.springframework.security
					spring-security-jwt
					1.0.10.RELEASE
				


				
					org.springframework.security.oauth.boot
					spring-security-oauth2-autoconfigure
					2.1.3.RELEASE
				


			
		


		

			


				
					org.apache.maven.plugins
					maven-compiler-plugin
					
						1.8
						1.8
					
				

				
					maven-resources-plugin
					
						utf-8
						true
					
				
			
		

	

3.1 、搭建一个认证服务器 oauth-authorizationServer

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第2张图片

001)、代码

	package com.feizhou.oauth.bean;

	import lombok.Data;

	/**
	 * 描述该类- JPA
	 *
	 * @author zhoufei
	 * @class: UserBean
	 * @date 2020/10/27 16:09
	 * @Verson 1.0 -2020/10/27 16:09
	 * @see
	 */

	@Data
	public class UserAuthorizeBean {
		private Long id;
		private Long userId;
		private String authorizeCode;
		
	}

	package com.feizhou.oauth.bean;

	import lombok.Data;

	/**
	 * 描述该类- JPA
	 *
	 * @author zhoufei
	 * @class: UserBean
	 * @date 2020/10/27 16:09
	 * @Verson 1.0 -2020/10/27 16:09
	 * @see
	 */

	@Data
	public class UserBean {
		private Long id;
		private String userName;
		private String password;
		
	}

	package com.feizhou.oauth.config;

	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.http.HttpMethod;
	import org.springframework.security.authentication.AuthenticationManager;
	import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
	import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
	import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
	import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
	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.ClientDetailsService;
	import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
	import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
	import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
	import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
	import org.springframework.security.oauth2.provider.token.TokenStore;
	import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

	/**
	 * 描述该类- JPA
	 *
	 * @author zhoufei
	 * @class: AuthorizationServer
	 * @date 2020/10/28 21:26
	 * @Verson 1.0 -2020/10/28 21:26
	 * @see
	 */

	@Configuration
	@EnableAuthorizationServer // 配置授权服务。
	public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
		
		// 用来配置客户端详情服务
		@Override
		public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
			// 这里是第三方合作用户的客户id,秘钥的配置
			// 使用in-memory存储
			clients.inMemory()
					// client_id,用户账号
					.withClient("c1")
					// 客户端密钥
					.secret(new BCryptPasswordEncoder().encode("secret"))
					// 资源列表,资源标识
					.resourceIds("res1")
					// 授权类型(4种)
					.authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit",
							"refresh_token")
					// 客戶端允许的授权范围
					.scopes("all")
					// false跳转到授权页面,让用户点击授权,如果是true,相当于自动点击授权,就不跳转授权页面
					.autoApprove(false)//
					// 加上验证回调地址,返回授权码信息
					.redirectUris("http://www.baidu.com");
			
			// 如果有多个用户,配置多个客户详情
			// .and().withClient()
			
		}
		
		@Autowired
		// 令牌存储策略
		private TokenStore tokenStore;
		@Autowired
		// 客户端详情服务,也就是configure(ClientDetailsServiceConfigurer clients)方法
		private ClientDetailsService clientDetailsService;
		
		// 令牌管理服务
		@Bean
		public AuthorizationServerTokenServices tokenService() {
			DefaultTokenServices service = new DefaultTokenServices();
			service.setClientDetailsService(clientDetailsService);
			service.setSupportRefreshToken(true);// 支持刷新
			service.setTokenStore(tokenStore);// 令牌存储
			service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
			service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天
			return service;
		}
		
		@Autowired
		// 授权码服务
		private AuthorizationCodeServices authorizationCodeServices;
		@Autowired
		// 认证管理
		private AuthenticationManager authenticationManager;
		@Autowired
		// 令牌管理服务
		private AuthorizationServerTokenServices authorizationServerTokenServices;
		
		@Override
		// 用来配置令牌(token)的访问端点
		public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
			endpoints
					// 密码模式需要
					.authenticationManager(authenticationManager)
					// 授权码模式需要
					.authorizationCodeServices(authorizationCodeServices)
					// 令牌管理服务
					.tokenServices(authorizationServerTokenServices).allowedTokenEndpointRequestMethods(HttpMethod.POST);// 允许post提交
		}
		
		@Bean
		// 授权码服务器
		public AuthorizationCodeServices authorizationCodeServices() {
			// 授权码模式的授权码采用内存方式存储
			return new InMemoryAuthorizationCodeServices();
		}
		
		@Override
		// 用来配置令牌端点的安全约束,拦截规则
		public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
			
			security
					// 提供公有密匙的端点,如果你使用JWT令牌的话, 允许
					.tokenKeyAccess("permitAll()")
					// oauth/check_token:用于资源服务访问的令牌解析端点,允许
					.checkTokenAccess("permitAll()")
					// 表单认证,申请令牌
					.allowFormAuthenticationForClients();
		}
		
		@Bean
		// 令牌存储策略
		public TokenStore tokenStore() {
			// 内存存储,普通令牌
			return new InMemoryTokenStore();
		}
	}

	package com.feizhou.oauth.config;

	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.security.authentication.AuthenticationManager;
	import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
	import org.springframework.security.config.annotation.web.builders.HttpSecurity;
	import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
	import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
	import org.springframework.security.crypto.password.PasswordEncoder;

	/**
	 * @author Administrator
	 * @version 1.0
	 **/
	@Configuration
	@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
	public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
		
		// 认证管理器
		@Override
		@Bean
		public AuthenticationManager authenticationManagerBean() throws Exception {
			return super.authenticationManagerBean();
		}
		
		// 密码编码器
		@Bean
		public PasswordEncoder passwordEncoder() {
			return new BCryptPasswordEncoder();
		}

		// 安全拦截机制
		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http.
					csrf().disable().

					authorizeRequests().
					antMatchers("/admin/p1").
					hasAnyAuthority("p1").

					antMatchers("/user/p2").
					hasAnyAuthority("p2").
					antMatchers("/login*")
					.permitAll().
					anyRequest().
					authenticated().
					and().
					formLogin();
			
		}
	}

	package com.feizhou.oauth.dao;

	import java.util.ArrayList;
	import java.util.List;

	import com.feizhou.oauth.bean.UserAuthorizeBean;
	import com.feizhou.oauth.bean.UserBean;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.jdbc.core.BeanPropertyRowMapper;
	import org.springframework.jdbc.core.JdbcTemplate;
	import org.springframework.stereotype.Repository;

	/**
	 * 描述该类- JPA
	 *
	 * @author zhoufei
	 * @class: UserBean
	 * @date 2020/10/27 16:09
	 * @Verson 1.0 -2020/10/27 16:09
	 * @see
	 */

	@Repository
	public class UserDao {
		@Autowired
		JdbcTemplate jdbcTemplate;
		
		// 根据账号查询用户信息
		public UserBean getUserByUsername(String username) {
			String sql = "select * from user where user_name = ?";
			// 连接数据库查询用户
			List list = jdbcTemplate.query(sql, new Object[] { username },
					new BeanPropertyRowMapper<>(UserBean.class));
			if (list != null && list.size() == 1) {
				return list.get(0);
			}
			return null;
		}
		
		// 根据用户id查询用户权限
		public List getAuthorize(Long userId) {
			String sql = "SELECT * FROM user_authorize WHERE user_id =?";
			List list = jdbcTemplate.query(sql, new Object[] { userId },
					new BeanPropertyRowMapper<>(UserAuthorizeBean.class));
			List authorizes = new ArrayList<>();
			list.forEach(c -> authorizes.add(c.getAuthorizeCode()));
			return authorizes;
		}
		
	}

	package com.feizhou.oauth.service;

	import java.util.List;

	import com.feizhou.oauth.bean.UserBean;
	import com.feizhou.oauth.dao.UserDao;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.security.core.userdetails.User;
	import org.springframework.security.core.userdetails.UserDetails;
	import org.springframework.security.core.userdetails.UserDetailsService;
	import org.springframework.security.core.userdetails.UsernameNotFoundException;
	import org.springframework.stereotype.Service;

	/**
	 * @author Administrator
	 * @version 1.0
	 **/
	@Service
	public class SpringDataUserDetailsService implements UserDetailsService {
		
		@Autowired
		UserDao userDao;
		
		// 根据账号查询用户信息,
		// 通过@Service将SpringDataUserDetailsService注入容器,通过UserDetailsService接口表明该类的类型是UserDetailsService
		@Override
		public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
			
			// 将来连接数据库根据账号查询用户信息
			UserBean bean = userDao.getUserByUsername(username);
			if (bean == null) {
				// 如果用户查不到,返回null,由provider来抛出异常
				return null;
			}
			
			// 查询当前数据库的用户资源权限
			List authorize = userDao.getAuthorize(bean.getId());
			String[] authorizeArr = new String[authorize.size()];
			authorize.toArray(authorizeArr);
			
			// 添加权限
			UserDetails userDetails = User.withUsername(bean.getUserName()).password(bean.getPassword())
					.authorities(authorizeArr).build();
			return userDetails;
		}
	}

application.properties

	spring.application.name=oauth-authorizationServer
	server.port=8081

	spring.datasource.url = jdbc:mysql://zhoufei.ali.db.com:3306/test?useUnicode=true
	spring.datasource.username = root
	spring.datasource.password = root
	spring.datasource.driver-class-name = com.mysql.jdbc.Driver

pom.xml

	
	
		
			oauth-parent
			oauth-learn
			1.0-SNAPSHOT
		
		4.0.0

		oauth-authorizationServer


		

			
				org.springframework.boot
				spring-boot-starter-web
			


			
				org.springframework.data
				spring-data-commons
			

			
				org.springframework.cloud
				spring-cloud-starter-security
			

			
				org.springframework.cloud
				spring-cloud-starter-oauth2
			

			
				org.springframework.security
				spring-security-jwt
			


			
				mysql
				mysql-connector-java
			
			
				org.springframework.boot
				spring-boot-starter-jdbc
			


			
				org.projectlombok
				lombok
			


		


	

002)、理论,解读代码

L1. OAuth2.0授权服务器的开启

  1. @EnableAuthorizationServer注解
  2. 继承AuthorizationServerConfigurerAdapter

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第3张图片

L2. AuthorizationServerConfigurerAdapter:

  1. 要配置以下几个类,通过重写以下方法来实现

    oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第4张图片

L3. ClientDetailsServiceConfigurer

  1. 用来配置客户端详情服务(ClientDetailsService )
    1. ClientDetailsService负责查找ClientDetails
  2. 可通过内存或者数据库来配置
  3. 客户端详情服务
    1. 第三方服务器来授权服务器申请访问资源。通过授权后,颁发clientId,secret给第三方服务器,表示第三方服务器是信任的服务器。

ClientDetails重要属性列表:

  1. clientId:标识客户的Id

  2. secret:客户端秘钥

  3. scope:限制客户端的访问范围

    1. 默认空:拥有全部的访问范围。
  4. authorizedGrantTypes:此客户端可以使用的授权类型

    1. 默认为空
  5. authorities:客户端可以使用的权限

    1. 基于SpringSecurityauthorities

ClientDetails介绍

  1. 能够在应用程序运行的时候进行更新
  2. 可以通过访问底层的存储服务
    1. 客户端详情存储在一个关系数据库的表中
    2. 实现方式
      1. 使用JdbcClientDetailsService
      2. 自己实现ClientRegistrationService接口
      3. 自己实现ClientDetailsService接口

具体代码

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第5张图片

L4. AuthorizationServerTokenServices

  1. 令牌管理服务
  2. 定义管理令牌的操作
  3. 令牌
    1. 用来加载身份信息
    2. 包含了这个令牌的相关权限。
  4. 这个接口的实现,则需要继承DefaultTokenServices

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第6张图片

DefaultTokenServices

  1. 可以修改令牌的格式
  2. 可以修改令牌的存储。
  3. 默认的,当它尝试创建一个令牌使用随机值来进行填充的,除了持久化令牌是委托一个TokenStore接口来实现以外,这个类几乎帮你做了所有的事情。

TokenStore

  1. 默认实现:InMemoryTokenStore

    1. 所有的令牌是被保存在了内存中
    2. 它可以完美的工作在单服务器上(即访问并发量压力不大的情况下,并且它在失败的时候不会进行备份)
  2. JdbcTokenStore

    1. 基于JDBC的实现版本,令牌会被保存进关系型数据库
    2. 注意点:需要把"spring-jdbc"这个依赖加入到你的classpath当中。
  3. JwtTokenStore

    1. 它可以把令牌相关的数据进行编码(因此对于后端服务来说,它不需要进行存储,这将是一个重大优势)
    2. 缺点:
      1. 撤销一个已经授权令牌非常困难,所以它通常用来处理一个生命周期较短的令牌以及撤销刷新令牌(refresh_token)
      2. 这个令牌占用的空间会比较大,如果你加入了比较多用户凭证信息。JwtTokenStore不会保存任何数据,但是它在转换令牌值以及授权信息方面与DefaultTokenServices所扮演的角色是一样的。

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第7张图片

L5. AuthorizationServerEndpointsConfigurer

  1. 可以完成令牌服务
  2. 可以完成令牌endpoint配置

配置授权类型(GrantTypes)

  1. authenticationManager:认证管理器
    1. 选择密码(password)授权类型的时候,请设置这个属性注入一个AuthenticationManager对象。
  2. userDetailsService:
    1. 设置UserDetailsService接口的实现类(用户登录验证)
    2. 或者你可以把这个东西设置到全局域上面去(例如GlobalAuthenticationManagerConfigurer这个配置对象),当你设置了这个之后,那么"refresh_token"即刷新令牌授权类型模式的流程中就会包含一个检查,用来确保这个账号是否仍然有效。
  3. authorizationCodeServices:设置授权码服务
    1. 用于"authorization_code"授权码类型模式
  4. implicitGrantService:设置隐式授权模式,用来管理隐式授权模式的状态。
  5. tokenGranter:
    1. 设置TokenGranter接口实现,授权将会交由你来完全掌控,并且会忽略掉上面的这几个属性
    2. 这个属性一般是用作拓展用途的,即标准的四种授权模式已经满足不了你的需求的时候,才会考虑使用这个。

具体代码

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第8张图片

配置授权端点的URL(EndpointURLs)

  1. AuthorizationServerEndpointsConfigurer有一个pathMapping()的方法用来配置端点URL链接
  2. 它有两个参数
    1. 第一个参数:String类型的,这个端点URL的默认链接。
    2. 第二个参数:String类型的,你要进行替代的URL链接。
    3. 以上的参数都将以"/"字符为开始的字符串,
    4. 框架的默认URL链接如下列表,可以作为这个pathMapping()方法的第一个参数
      1. /oauth/authorize:授权端点。
      2. /oauth/token:令牌端点。
      3. /oauth/confirm_access:用户确认授权提交端点。
      4. /oauth/error:授权服务错误信息端点。
      5. /oauth/check_token:用于资源服务访问的令牌解析端点。
      6. /oauth/token_key:提供公有密匙的端点,如果你使用JWT令牌的话。需要注意的是授权端点这个URL应该被SpringSecurity保护起来只供授权用户访问。

L7. authorizationCodeServices

  1. 授权码服务的存储方式

具体代码

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第9张图片


L8. AuthorizationServerSecurityConfigurer

  1. 令牌端点的安全约束

  2. tokenkey:/oauth/token_key端点完全公开。

  3. checkToken:/oauth/check_token端点完全公开。

  4. allowFormAuthenticationForClients:允许表单认证
    具体代码


oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第10张图片

3.2 、验证认证服务器

001) 、授权码模式

http://localhost:8081/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com

先让你登录(Security的原因)

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第11张图片

用户授权

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第12张图片

返回授权码

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第13张图片

请求taken

http://localhost:8081/oauth/token?client_id=c1&client_secret=secret&grant_type=authorization_code&code=kZAlHW&redirect_uri=http://www.baidu.com

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第14张图片

002) 、简化模式

http://localhost:8081/oauth/authorize?client_id=c1&response_type=token&scope=all&redirect_uri=http://www.baidu.com

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第15张图片

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第16张图片

003) 、密码模式

http://localhost:8081/oauth/token?client_id=c1&client_secret=secret&grant_type=password&username=admin&password=admin

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第17张图片

004) 、客户端模式

http://localhost:8081/oauth/token?client_id=c1&client_secret=secret&grant_type=client_credentials

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第18张图片

3.3 、搭建一个授权服务器 oauth-authorizationServer

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第19张图片

001)、代码

	package com.feizhou.oauth.config;

	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.security.config.annotation.web.builders.HttpSecurity;
	import org.springframework.security.config.http.SessionCreationPolicy;
	import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
	import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
	import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
	import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
	import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

	/**
	 * @author Administrator
	 * @version 1.0
	 **/
	@Configuration
	@EnableResourceServer
	public class ResouceServerConfig extends ResourceServerConfigurerAdapter {
		
		// 授权服务的资源列表
		public static final String RESOURCE_ID = "res1";
		
		@Override
		public void configure(ResourceServerSecurityConfigurer resources) {
			resources
					// 资源 id
					.resourceId(RESOURCE_ID)
					// 令牌服务
					.tokenServices(tokenService())
					.stateless(true);
		}
		
		@Override
		public void configure(HttpSecurity http) throws Exception {
			
			http
					
					.authorizeRequests().antMatchers("/**")
					// 所有的访问,授权访问都要是all,和认证服务器的授权范围一一对应
					.access("#oauth2.hasScope('all')")
					//去掉防跨域攻击
					.and().csrf().disable()
					//session管理
					.sessionManagement()
					.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
		}
		
		@Bean
		// 资源服务令牌解析服务
		public ResourceServerTokenServices tokenService() {
			// 使用远程服务请求授权服务器校验token,必须指定校验token 的url、client_id,client_secret
			RemoteTokenServices service = new RemoteTokenServices();
			service.setCheckTokenEndpointUrl("http://localhost:8081/oauth/check_token");
			service.setClientId("c1");
			service.setClientSecret("secret");
			return service;
		}
		
	}

	package com.feizhou.oauth.config;

	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
	import org.springframework.security.config.annotation.web.builders.HttpSecurity;
	import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
	import org.springframework.security.config.http.SessionCreationPolicy;
	import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
	import org.springframework.security.crypto.password.PasswordEncoder;

	//由于Spring boot starter自动装配机制,这里无需使用@EnableWebSecurity
	//@EnableWebSecurity
	@Configuration
	@EnableGlobalMethodSecurity(prePostEnabled = true) // 方法授权
	public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
		
		// 密码编码器,不加密
		@Bean
		public PasswordEncoder passwordEncoder() {
			// return NoOpPasswordEncoder.getInstance(); // 不加密
			return new BCryptPasswordEncoder();// BCryptPasswordEncoder加密
		}
		
		// web url 拦截规则
		@Override
		protected void configure(HttpSecurity http) throws Exception {
			http.authorizeRequests()
					
					.anyRequest().authenticated()// 所有其他请求必须认证通过
					.and().formLogin().loginPage("/login").successForwardUrl("/login-success")// 自定义登录成功的页面地址
					.permitAll().and().logout().permitAll().and()// 会话管理
					.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);// 会话管理
		}
	}

	package com.feizhou.oauth.controller;

	import org.springframework.security.access.prepost.PreAuthorize;
	import org.springframework.security.core.Authentication;
	import org.springframework.security.core.context.SecurityContextHolder;
	import org.springframework.security.core.userdetails.UserDetails;
	import org.springframework.web.bind.annotation.GetMapping;
	import org.springframework.web.bind.annotation.RequestMapping;
	import org.springframework.web.bind.annotation.RestController;

	/**
	 * @author Administrator
	 * @version 1.0
	 **/
	@RestController
	public class LoginController {

		@RequestMapping(value = "/login-success")
		public String loginSuccess() {
			return getUsername() + " login-success 登录成功";
		}

		/**
		 * 测试资源1
		 *
		 * @return
		 */
		@GetMapping(value = "/admin/p1")
		@PreAuthorize("hasAuthority('p1')")//拥有p1权限才可以访问
		public String r1() {
			return " /admin/p1 " + getUsername() + "访问资源1";
		}

		/**
		 * 测试资源2
		 *
		 * @return
		 */
		@GetMapping(value = "/user/p2")
		@PreAuthorize("hasAuthority('p2')")//拥有p2权限才可以访问
		public String r2() {
			return "/user/p2 " + getUsername() + "访问资源2";
		}

		// 获取当前用户信息
		private String getUsername() {
			String username = null;
			// 当前认证通过的用户身份
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			// 用户身份
			Object principal = authentication.getPrincipal();
			if (principal == null) {
				username = "匿名";
			}
			if (principal instanceof UserDetails) {
				UserDetails userDetails = (UserDetails) principal;
				username = userDetails.getUsername();
			} else {
				username = principal.toString();
			}
			return username;
		}
	}

application.properties

	spring.application.name=oauth-ResourceServer
	server.port=8082

pom.xml

	
	
		
			oauth-parent
			oauth-learn
			1.0-SNAPSHOT
		
		4.0.0

		oauth-ResourceServer

		

			
				org.springframework.boot
				spring-boot-starter-web
			

			
				org.springframework.cloud
				spring-cloud-starter-security
			
			
				org.springframework.cloud
				spring-cloud-starter-oauth2
			

			
				org.projectlombok
				lombok
			


		
	

002)、代码解读和理论

L1. OAuth2.0资源服务器的开启

  1. @EnableResourceServer注解
    1. 会自动增加了一个类型为OAuth2AuthenticationProcessingFilter的过滤器链
  2. 继承ResourceServerConfigurerAdapter

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第20张图片

L2. ResourceServerSecurityConfigurer

  1. tokenServices:

    1. ResourceServerTokenServices类的实例
    2. 用来实现令牌服务
  2. tokenStore:

    1. TokenStore类的实例,指定令牌如何访问,与tokenServices配置可选
  3. resourceId

    1. 这个资源服务的ID,这个属性是可选的,推荐设置并在授权服务中进行验证
  4. tokenExtractor

    1. 令牌提取器用来提取请求中的令牌

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第21张图片

L3. HttpSecurity配置这个与Spring Security类似

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第22张图片

L4. ResourceServerTokenServices

  1. DefaultTokenServices

    1. 授权服务和资源服务在同一个应用程序上可以使用
    2. 在资源服务器本地配置令牌存储、解码、解析方式使用
  2. RemoteTokenServices

    1. 资源服务器通过HTTP请求来解码令牌
    2. 请求端点:/oauth/check_token

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第23张图片

003)、测试

获取token

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第24张图片

检查token的信息

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第25张图片

admin请求可以访问的资源

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第26张图片

user请求可以访问的资源(token 是admin的)

oauth2.0系统学习3-简单搭建spring sercurity+oauth2.0的框架_第27张图片

代码文章
https://gitee.com/DanShenGuiZu/learnDemo/tree/mysql_mybaties_DB/oauth2.0-learn

你可能感兴趣的:(OAuth2)