package com.css.simulation.resource.scene.common.config;

import com.css.simulation.resource.scene.common.oauth.MyUserAuthenticationConverter;
import com.css.simulation.resource.scene.common.oauth.OauthParameter;
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.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;

import javax.annotation.Resource;

@Configuration
public class OAuth2Config extends ResourceServerConfigurerAdapter {

    @Resource
    private OauthParameter oauthParameter;

    @Resource
    MyUserAuthenticationConverter myUserAuthenticationConverter;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        //令牌解析服务配置
        RemoteTokenServices services = new RemoteTokenServices();
        services.setCheckTokenEndpointUrl(oauthParameter.getCheckTokenEndpointUrl());  // 需要在授权服务器公开 /oauth/check_token
        services.setClientId(oauthParameter.getClientId());
        services.setClientSecret(oauthParameter.getClientSecret());
        //自定义令牌转换器
        DefaultAccessTokenConverter defaultAccessTokenConverter = new DefaultAccessTokenConverter();
        defaultAccessTokenConverter.setUserTokenConverter(myUserAuthenticationConverter);
        services.setAccessTokenConverter(defaultAccessTokenConverter);
        resources.resourceId(oauthParameter.getResourceId())      // 资源 id
                .tokenServices(services)    // 使用远程服务验证令牌的服务
                .stateless(true);   // 无状态模式，即无需用户登录，无 session
    }

    /**
     * 配置拦截请求，通过 scope
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()   // 禁用 csrf
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)// 无状态验证
                .and()
                .authorizeRequests()
                .antMatchers("/druid/**").permitAll()
                .anyRequest().access("#oauth2.hasScope('all')") // 拦截所有请求判断 scope
        ;
    }
}
