package com.ym.mec.auth.config;

import com.ym.mec.common.constant.CommonConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
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.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;

/**
 * 授权服务器配置
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

	@Autowired
	private RedisConnectionFactory connectionFactory;
	@Autowired
	private AuthenticationManager authenticationManager;

	@Autowired
	private DataSource dataSource;

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints){
		endpoints
				.authenticationManager(authenticationManager)
				.tokenServices(defaultTokenServices())
				.tokenStore(redisTokenStore());
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer security){
		security.tokenKeyAccess("isAuthenticated()")
				.checkTokenAccess("permitAll()")
				.allowFormAuthenticationForClients();
	}

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

		JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);

		clientDetailsService
				.setSelectClientDetailsSql("select id_, CONCAT('{noop}',client_secret_) as client_secret, resource_ids_, scope_, authorized_grant_types_, web_server_redirect_uri_, authorities_, access_token_validity_, refresh_token_validity_, additional_information_, autoapprove_ from sys_oauth_client_details where id_ = ?");
		clientDetailsService
				.setFindClientDetailsSql("select id_, CONCAT('{noop}',client_secret_) as client_secret, resource_ids_, scope_, authorized_grant_types_, web_server_redirect_uri_, authorities_, access_token_validity_, refresh_token_validity_, additional_information_, autoapprove_ from sys_oauth_client_details order by id_");

		clients.withClientDetails(clientDetailsService);
	}

	@Bean
	public RedisTokenStore redisTokenStore() {
		RedisTokenStore tokenStore = new RedisTokenStore(connectionFactory);
		tokenStore.setPrefix(CommonConstants.OAUTH_PREFIX);
		return tokenStore;
	}

	@Bean
	public DefaultTokenServices defaultTokenServices() {
		DefaultTokenServices tokenServices = new DefaultTokenServices();
		tokenServices.setTokenStore(redisTokenStore());
		tokenServices.setSupportRefreshToken(true);
		//tokenServices.setAccessTokenValiditySeconds(60 * 60 * 24); // token有效期自定义设置，默认12小时
		//tokenServices.setRefreshTokenValiditySeconds(60 * 60 * 24 * 30);// 默认30天，这里修改
		return tokenServices;
	}

}
