Spring Security 及 OAuth2 中 **ConfigurerAdapter 的關(guān)系

Spring Security 及 OAuth2 中 **ConfigurerAdapter 的關(guān)系

Spring SecurityOAuth2WebSecurityConfigurerAdapter,
AuthorizationServerConfigurerAdapter繁莹,ResourceServerConfigurerAdapter
之間啥關(guān)系


安全服務(wù)配置類


@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

實現(xiàn)接口WebSecurityConfigurer娘侍,項目中繼承于此類進行配置

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

結(jié)論

@EnableWebSecurity 加載 WebSecurityConfiguration睦柴,其又去加載WebSecurityConfigurerAdapter(代碼里是加載WebSecurityConfigurer接口的實現(xiàn)類,但 WebSecurityConfiguration 中的成員變量是 SecurityConfigurer



認證服務(wù)安全配置類


@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虑椎,用于簡化配置類實現(xiàn)

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 {
    }

}

資源服務(wù)配置類


@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

資源服務(wù)的具體配置類纲爸,由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

實現(xiàn)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();
    }

}

總結(jié):

  • AuthorizationServerSecurityConfigurationResourceServerConfiguration其本質(zhì)繼承于WebSecurityConfigurerAdapter的配置類,其最終被WebSecurityConfiguration加載
  • AuthorizationServerConfigurerAdapterAuthorizationServerSecurityConfiguration
    ResourceServerConfigurerAdapterResourceServerConfiguration的關(guān)系類似于WebSecurityConfigurerAdapterWebSecurityConfiguration的關(guān)系识啦,但層次不一樣
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末负蚊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子袁滥,更是在濱河造成了極大的恐慌盖桥,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件题翻,死亡現(xiàn)場離奇詭異揩徊,居然都是意外死亡,警方通過查閱死者的電腦和手機嵌赠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門塑荒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姜挺,你說我怎么就攤上這事齿税。” “怎么了炊豪?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵凌箕,是天一觀的道長拧篮。 經(jīng)常有香客問我,道長牵舱,這世上最難降的妖魔是什么串绩? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮芜壁,結(jié)果婚禮上礁凡,老公的妹妹穿的比我還像新娘。我一直安慰自己慧妄,他們只是感情好顷牌,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著塞淹,像睡著了一般窟蓝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窖铡,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天疗锐,我揣著相機與錄音,去河邊找鬼费彼。 笑死滑臊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的箍铲。 我是一名探鬼主播雇卷,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼颠猴!你這毒婦竟也來了关划?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤翘瓮,失蹤者是張志新(化名)和其女友劉穎贮折,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體资盅,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡调榄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了呵扛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片每庆。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖今穿,靈堂內(nèi)的尸體忽然破棺而出缤灵,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布腮出,位于F島的核電站帖鸦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏利诺。R本人自食惡果不足惜富蓄,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望慢逾。 院中可真熱鬧,春花似錦灭红、人聲如沸侣滩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽君珠。三九已至,卻和暖如春娇斑,著一層夾襖步出監(jiān)牢的瞬間策添,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工毫缆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唯竹,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓苦丁,卻偏偏與公主長得像浸颓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子旺拉,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容