Spring Security OAuth2+JWT授权认证服务

添加依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-oauth2</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-security</artifactId>
		</dependency>
		
		<dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		
        		<dependency>
		  <groupId>org.projectlombok</groupId>
		  <artifactId>lombok</artifactId>
		</dependency>
		
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.47</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.47</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

其中添加的有mysql数据库访问 和 数据源操作支持用于,读取用户、用户权限资源配置等信息。

JWT token生成配置:

@Configuration
public class JwtTokeStoreConfig {
	
	private String KEY = "aaa";
	
	@Bean
	public JwtTokenStore tokenStore() {
		return new JwtTokenStore(accessTokenConverter());
	}
	
	@Bean
	public JwtAccessTokenConverter accessTokenConverter() {
		JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
		converter.setSigningKey(KEY);
		return converter;
	}
}

认证服务配置(AuthorizationServerConfig)

@Configuration
@EnableAuthorizationServer
public class JwtAuthorizationConfig extends AuthorizationServerConfigurerAdapter {
	
	@Autowired
	private PasswordEncoder passwordEncoder;

	@Autowired
    private DataSource dataSource;
	
	@Autowired
	private TokenStore tokenStore;
	
	@Autowired
	private JwtAccessTokenConverter accessTokenConverter;
	
	private ClientDetailsService clientDetailsService() {
		ClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
		((JdbcClientDetailsService) clientDetailsService).setPasswordEncoder(passwordEncoder);
		return clientDetailsService;
	}
	
	//1.配置客户端详情服务----------
	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients.withClientDetails(clientDetailsService());
	}
	
	@Bean
	public AuthorizationServerTokenServices tokenService() {
		DefaultTokenServices services = new DefaultTokenServices();
		services.setClientDetailsService(clientDetailsService()); // 客户端信息服务
		services.setSupportRefreshToken(true); //是否产生刷新令牌
		services.setTokenStore(tokenStore); //令牌存储策略
		// JWT 令牌增强
		TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
		tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
		services.setTokenEnhancer(tokenEnhancerChain);
		
		services.setAccessTokenValiditySeconds(7200);//生成有效时间
		services.setRefreshTokenValiditySeconds(29000);//刷新令牌有效时间
		
		return services;
	}
	
	//授权码服务
	@Bean
	public AuthorizationCodeServices authorizationCodeServices() {
		//设置授权码模式的授权码如何存储(数据库)
		return new JdbcAuthorizationCodeServices(dataSource);
		//设置授权码模式的授权码如何存储(内存)
		//return new InMemoryAuthorizationCodeServices();
	}	
	
	@Autowired
	private AuthenticationManager authenticationManager; //认证管理器
	//2.令牌访问端点
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.authenticationManager(authenticationManager) //认证管理器
				.accessTokenConverter(accessTokenConverter)
				.authorizationCodeServices(authorizationCodeServices()) //授权码服务
				.tokenServices(tokenService()) // 令牌管理服务
				.allowedTokenEndpointRequestMethods(HttpMethod.POST); //允许 post 提交
	}
	
	//3.令牌访问安全策略
	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
		security.allowFormAuthenticationForClients() //表单认证申请令牌
				.tokenKeyAccess("permitAll()") // 获取令牌公开
				.checkTokenAccess("permitAll()"); // 检测令牌公开
	}
	
}

        配置OAuth2认证允许接入的客户端的信息,因为接入OAuth2认证服务器首先人家得认可你这个客户端吧。

        同理,我们需要把客户端信息配置在认证服务器上来表示认证服务器所认可的客户端。一般可配置在认证服务器的内存中,但是这样很不方便管理扩展。所以实际最好配置在数据库中的,提供可视化界面对其进行管理,方便以后像PC端、APP端、小程序端等多端灵活接入。

Spring Security OAuth2官方提供的客户端信息表oauth_client_details
CREATE TABLE `oauth_client_details`  (
  `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `access_token_validity` int(11) NULL DEFAULT NULL,
  `refresh_token_validity` int(11) NULL DEFAULT NULL,
  `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `oauth_client_details` VALUES ('res1', NULL, '123456', 'all', 'password,refresh_token', '', NULL, NULL, NULL, NULL, NULL);

安全配置(WebSecurityConfig)

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
	
	//认证管理器
	@Bean
	public AuthenticationManager authenticationManager() throws Exception {
		return super.authenticationManager();
	}
	
	@Bean
	public PasswordEncoder passwordEncoder() {
		return NoOpPasswordEncoder.getInstance();
	}
	
	//3.安全拦截机制
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable()
			.authorizeRequests()
			.anyRequest().permitAll() //其它可以直接访问
			.and()
			.formLogin(); //允许表单登录
			//.successForwardUrl("/login-success"); //自定义登录成功页面地址
	}
}

最后做配置就可以了,配置就写在Spring Boot的配置文件application.yml中

server:
  port: 8080

# 注册服务中心配置
eureka:
  client:
    service-url:
      defaultZone: http://admin:123456@localhost:8001/eureka/
  
spring:
  application:
    name: oauth
 # 数据源配置 
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/dataName
    username: root
    password: root
  jpa:
    show-sql: true

 

上一篇:SpringBootSecurity学习(21)前后端分离版之OAuth2.0非对称加密


下一篇:Spring cloud微服务安全实战-4-4 OAuth2协议与微服务安全