美文网首页
Spring Security 及 OAuth2 中 **Con

Spring Security 及 OAuth2 中 **Con

作者: 帅气地看着书 | 来源:发表于2021-03-07 19:59 被阅读0次

    Spring Security 及 OAuth2 中 **ConfigurerAdapter 的关系

    Spring SecurityOAuth2WebSecurityConfigurerAdapter,
    AuthorizationServerConfigurerAdapter,ResourceServerConfigurerAdapter
    之间啥关系


    安全服务配置类


    @EnableWebSecurity

    加载WebSecurityConfiguration

    @Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
    @Target(value = { java.lang.annotation.ElementType.TYPE })
    @Documented
    @Import({ WebSecurityConfiguration.class,
            SpringWebMvcImportSelector.class,
            OAuth2ImportSelector.class })
    @EnableGlobalAuthentication
    @Configuration
    public @interface EnableWebSecurity {
    
        /**
         * Controls debugging support for Spring Security. Default is false.
         * @return if true, enables debug support with Spring Security
         */
        boolean debug() default false;
    }
    
    

    WebSecurityConfiguration

    @EnableWebSecurity注解加载

    @Configuration
    public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
        private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers;
    
        @Autowired(required = false)
        public void setFilterChainProxySecurityConfigurer(
                ObjectPostProcessor<Object> objectPostProcessor,
                @Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
                throws Exception {
            webSecurity = objectPostProcessor
                    .postProcess(new WebSecurity(objectPostProcessor));
            if (debugEnabled != null) {
                webSecurity.debug(debugEnabled);
            }
    
            Collections.sort(webSecurityConfigurers, AnnotationAwareOrderComparator.INSTANCE);
    
            Integer previousOrder = null;
            Object previousConfig = null;
            for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
                Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
                if (previousOrder != null && previousOrder.equals(order)) {
                    throw new IllegalStateException(
                            "@Order on WebSecurityConfigurers must be unique. Order of "
                                    + order + " was already used on " + previousConfig + ", so it cannot be used on "
                                    + config + " too.");
                }
                previousOrder = order;
                previousConfig = config;
            }
            for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
                webSecurity.apply(webSecurityConfigurer);
            }
            this.webSecurityConfigurers = webSecurityConfigurers;
        }
    
        @Bean
        public static AutowiredWebSecurityConfigurersIgnoreParents autowiredWebSecurityConfigurersIgnoreParents(
                ConfigurableListableBeanFactory beanFactory) {
            return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
        }
    }
    
    /**
     * A class used to get all the {@link WebSecurityConfigurer} instances from the current
     * {@link ApplicationContext} but ignoring the parent.
     *
     * @author Rob Winch
     *
     */
    final class AutowiredWebSecurityConfigurersIgnoreParents {
    
        private final ConfigurableListableBeanFactory beanFactory;
    
        public AutowiredWebSecurityConfigurersIgnoreParents(
                ConfigurableListableBeanFactory beanFactory) {
            Assert.notNull(beanFactory, "beanFactory cannot be null");
            this.beanFactory = beanFactory;
        }
    
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public List<SecurityConfigurer<Filter, WebSecurity>> getWebSecurityConfigurers() {
            List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers = new ArrayList<SecurityConfigurer<Filter, WebSecurity>>();
            Map<String, WebSecurityConfigurer> beansOfType = beanFactory
                    .getBeansOfType(WebSecurityConfigurer.class);
            for (Entry<String, WebSecurityConfigurer> entry : beansOfType.entrySet()) {
                webSecurityConfigurers.add(entry.getValue());
            }
            return webSecurityConfigurers;
        }
    }
    

    SecurityConfigurer

    安全配置接口类

    public interface SecurityConfigurer<O, B extends SecurityBuilder<O>> {
        /**
         * Initialize the {@link SecurityBuilder}. Here only shared state should be created
         * and modified, but not properties on the {@link SecurityBuilder} used for building
         * the object. This ensures that the {@link #configure(SecurityBuilder)} method uses
         * the correct shared objects when building.
         *
         * @param builder
         * @throws Exception
         */
        void init(B builder) throws Exception;
    
        /**
         * Configure the {@link SecurityBuilder} by setting the necessary properties on the
         * {@link SecurityBuilder}.
         *
         * @param builder
         * @throws Exception
         */
        void configure(B builder) throws Exception;
    }
    

    WebSecurityConfigurer

    继承于SecurityConfigurer

    public interface WebSecurityConfigurer<T extends SecurityBuilder<Filter>> extends
            SecurityConfigurer<Filter, T> {
    
    }
    

    WebSecurityConfigurerAdapter

    实现接口WebSecurityConfigurer,项目中继承于此类进行配置

    @Order(100)
    public abstract class WebSecurityConfigurerAdapter implements
            WebSecurityConfigurer<WebSecurity> {
    }
    

    结论

    @EnableWebSecurity 加载 WebSecurityConfiguration,其又去加载WebSecurityConfigurerAdapter(代码里是加载WebSecurityConfigurer接口的实现类,但 WebSecurityConfiguration 中的成员变量是 SecurityConfigurer



    认证服务安全配置类


    @EnableAuthorizationServer

    其加载AuthorizationServerSecurityConfiguration配置文件

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AuthorizationServerEndpointsConfiguration.class, AuthorizationServerSecurityConfiguration.class})
    public @interface EnableAuthorizationServer {
    
    }
    

    AuthorizationServerSecurityConfiguration

    继承于WebSecurityConfigurerAdapter,由@EnableAuthorizationServer注释加载
    此处就可以知道继承于WebSecurityConfigurerAdapter的配置,其最终由WebSecurityConfiguration加载

    @Configuration
    @Order(0)
    @Import({ ClientDetailsServiceConfiguration.class, AuthorizationServerEndpointsConfiguration.class })
    public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Autowired
        private List<AuthorizationServerConfigurer> configurers = Collections.emptyList();
    }
    

    AuthorizationServerConfigurer

    注入到AuthorizationServerSecurityConfiguration的成员变量configurers

    public interface AuthorizationServerConfigurer {
    
        /**
         * Configure the security of the Authorization Server, which means in practical terms the /oauth/token endpoint. The
         * /oauth/authorize endpoint also needs to be secure, but that is a normal user-facing endpoint and should be
         * secured the same way as the rest of your UI, so is not covered here. The default settings cover the most common
         * requirements, following recommendations from the OAuth2 spec, so you don't need to do anything here to get a
         * basic server up and running.
         * 
         * @param security a fluent configurer for security features
         */
        void configure(AuthorizationServerSecurityConfigurer security) throws Exception;
    
        /**
         * Configure the {@link ClientDetailsService}, e.g. declaring individual clients and their properties. Note that
         * password grant is not enabled (even if some clients are allowed it) unless an {@link AuthenticationManager} is
         * supplied to the {@link #configure(AuthorizationServerEndpointsConfigurer)}. At least one client, or a fully
         * formed custom {@link ClientDetailsService} must be declared or the server will not start.
         * 
         * @param clients the client details configurer
         */
        void configure(ClientDetailsServiceConfigurer clients) throws Exception;
    
        /**
         * Configure the non-security features of the Authorization Server endpoints, like token store, token
         * customizations, user approvals and grant types. You shouldn't need to do anything by default, unless you need
         * password grants, in which case you need to provide an {@link AuthenticationManager}.
         * 
         * @param endpoints the endpoints configurer
         */
        void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception;
    
    }
    

    AuthorizationServerConfigurerAdapter

    继承于AuthorizationServerConfigurer,用于简化配置类实现

    public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer {
    
        @Override
        public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        }
    
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        }
    
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        }
    
    }
    

    资源服务配置类


    @EnableResourceServer

    加载ResourceServerConfiguration配置类

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(ResourceServerConfiguration.class)
    public @interface EnableResourceServer {
    
    }
    

    ResourceServerConfiguration

    继承于WebSecurityConfigurerAdapter,由注释@EnableResourceServer加载

    @Configuration
    public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered {
    
        private int order = 3;
    
        private List<ResourceServerConfigurer> configurers = Collections.emptyList();
    
        /**
         * @param configurers the configurers to set
         */
        @Autowired(required = false)
        public void setConfigurers(List<ResourceServerConfigurer> configurers) {
            this.configurers = configurers;
        }
    }
    

    ResourceServerConfigurer

    资源服务的具体配置类,由ResourceServerConfiguration加载

    public interface ResourceServerConfigurer {
    
        /**
         * Add resource-server specific properties (like a resource id). The defaults should work for many applications, but
         * you might want to change at least the resource id.
         * 
         * @param resources configurer for the resource server
         * @throws Exception if there is a problem
         */
        void configure(ResourceServerSecurityConfigurer resources) throws Exception;
    
        /**
         * Use this to configure the access rules for secure resources. By default all resources <i>not</i> in "/oauth/**"
         * are protected (but no specific rules about scopes are given, for instance). You also get an
         * {@link OAuth2WebSecurityExpressionHandler} by default.
         * 
         * @param http the current http filter configuration
         * @throws Exception if there is a problem
         */
        void configure(HttpSecurity http) throws Exception;
    
    }
    

    ResourceServerConfigurerAdapter

    实现ResourceServerConfigurer接口,默认情况下继承此类进行配置

    public class ResourceServerConfigurerAdapter implements ResourceServerConfigurer {
    
        @Override
        public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        }
    
        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated();
        }
    
    }
    

    总结:

    • AuthorizationServerSecurityConfigurationResourceServerConfiguration其本质继承于WebSecurityConfigurerAdapter的配置类,其最终被WebSecurityConfiguration加载
    • AuthorizationServerConfigurerAdapterAuthorizationServerSecurityConfiguration
      ResourceServerConfigurerAdapterResourceServerConfiguration的关系类似于WebSecurityConfigurerAdapterWebSecurityConfiguration的关系,但层次不一样

    相关文章

      网友评论

          本文标题:Spring Security 及 OAuth2 中 **Con

          本文链接:https://www.haomeiwen.com/subject/ouqafltx.html