赞
踩
本文链接:https://blog.csdn.net/sinat_29899265/article/details/80736498
这是Spring Security入门指南中表单登陆的基本配置:
- @EnableWebSecurity
- @EnableGlobalMethodSecurity(prePostEnabled = true)
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .antMatchers("/", "/home").permitAll()
- .anyRequest().authenticated()
- .and()
- .formLogin()
- .loginPage("/login")
- .failureUrl("/error")
- .permitAll()
- .and()
- .logout()
- .permitAll();
- }
-
- @Autowired
- public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
- auth
- .inMemoryAuthentication()
- .withUser("user").password("password").roles("USER");
- }
- }
首先解释一下类上面的配置:
接下来我们解释一下这样配置的作用:
- @Import({ WebSecurityConfiguration.class,
- SpringWebMvcImportSelector.class })
- @EnableGlobalAuthentication
- @Configuration
- public @interface EnableWebSecurity {
- boolean debug() default false;
- }
- @Import(AuthenticationConfiguration.class)
- @Configuration
- public @interface EnableGlobalAuthentication {
- }
可以看出,这个注解引入了AuthenticationConfiguration配置。而这个类用来配置认证相关,主要任务就是生成全局的身份认证管理者。AuthenticationManager:
- @Configuration
- @Import(ObjectPostProcessorConfiguration.class)
- public class AuthenticationConfiguration {
-
- private AuthenticationManager authenticationManager;
-
- @Bean
- public AuthenticationManagerBuilder authenticationManagerBuilder(
- ObjectPostProcessor<Object> objectPostProcessor) {
- return new AuthenticationManagerBuilder(objectPostProcessor);
- }
-
- public AuthenticationManager getAuthenticationManager() throws Exception {
- ...
- }
-
- }
- @Configuration
- public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
-
- /**
- * Creates the Spring Security Filter Chain
- * @return
- * @throws Exception
- */
- @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
- public Filter springSecurityFilterChain() throws Exception {
- boolean hasConfigurers = webSecurityConfigurers != null
- && !webSecurityConfigurers.isEmpty();
- if (!hasConfigurers) {
- WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
- .postProcess(new WebSecurityConfigurerAdapter() {
- });
- webSecurity.apply(adapter);
- }
- return webSecurity.build();
- }
- }
在未使用springboot之前,在XML配置中,想要启用spring security,需要在web.xml中进行如下配置:
- <filter>
- <filter-name>springSecurityFilterChain</filter-name>
- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
- </filter>
-
- <filter-mapping>
- <filter-name>springSecurityFilterChain</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
而众所周知,SpringSecurityFilterChain是Spring Security认证的入口。集成Spring Boot集成之后,xml配置被java注解配置取代,也就是在WebSecurityConfiguration中完成了声明springSecurityFilterChain的作用。并且最终交给DelegatingFilterProxy这个代理类,负责拦截请求。
也就是说:@EnableWebSecurity完成的工作便是加载了WebSecurityConfiguration,AuthenticationConfiguration这两个核心配置类,也就此将spring security的职责划分为了配置安全信息,配置认证信息两部分。
WebSecurityConfigurerAdapter提供了三个configure方法,是我们需要关心的:
可以看出,分别是对AuthenticationManagerBuilder,WebSecurity,HttpSecurity进行个性化的配置。
常用配置:
- @Configuration
- @EnableWebSecurity
- public class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter {
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .antMatchers("/resources/**", "/signup", "/about").permitAll()
- .antMatchers("/admin/**").hasRole("ADMIN")
- .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
- .anyRequest().authenticated()
- .and()
- .formLogin()
- .usernameParameter("username")
- .passwordParameter("password")
- .failureForwardUrl("/login?error")
- .loginPage("/login")
- .permitAll()
- .and()
- .logout()
- .logoutUrl("/logout")
- .logoutSuccessUrl("/index")
- .permitAll()
- .and()
- .httpBasic()
- .disable();
- }
- }
上述是一个使用Java Configuration配置HttpSecurity的典型配置,其中http作为根开始配置,每一个and()对应了一个模块的配置(等同于xml配置中的结束标签),并且and()返回了HttpSecurity本身,于是可以连续进行配置。他们配置的含义也非常容易通过变量本身来推测。
他们分别代表了http请求相关的安全配置,这些配置项无一例外的返回了Configurer类,而所有的http相关配置可以通过查看HttpSecurity的主要方法得知:
- public final class WebSecurity {
- //全局请求忽略规则配置(比如说静态文件,比如说注册页面)
- public IgnoredRequestConfigurer ignoring() {
- return ignoredRequestRegistry;
- }
- //全局http防火墙配置
- public WebSecurity httpFirewall(HttpFirewall httpFirewall) {
- this.httpFirewall = httpFirewall;
- return this;
- }
- //是否debug配置
- public WebSecurity debug(boolean debugEnabled) {
- this.debugEnabled = debugEnabled;
- return this;
- }
-
- //全局SecurityFilterChain配置
- public WebSecurity addSecurityFilterChainBuilder(
- SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder) {
- this.securityFilterChainBuilders.add(securityFilterChainBuilder);
- return this;
- }
- //web权限评估器,默认DefaultWebInvocationPrivilegeEvaluator
- public WebSecurity privilegeEvaluator(
- WebInvocationPrivilegeEvaluator privilegeEvaluator) {
- this.privilegeEvaluator = privilegeEvaluator;
- return this;
- }
-
- //设置表达式处理器,默认DefaultWebSecurityExpressionHandler
- public WebSecurity expressionHandler(
- SecurityExpressionHandler<FilterInvocation> expressionHandler) {
- Assert.notNull(expressionHandler, "expressionHandler cannot be null");
- this.expressionHandler = expressionHandler;
- return this;
- }
- }
一般只有ignoring()配置需要重写:
- @Configuration
- @EnableWebSecurity
- public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
- @Override
- public void configure(WebSecurity web) throws Exception {
- web
- .ignoring()
- .antMatchers("/static/**");
- }
- }
主要的方法:
- public class AuthenticationManagerBuilder {
- //配置父AuthenticationManager
- public AuthenticationManagerBuilder parentAuthenticationManager(
- AuthenticationManager authenticationManager) {
- ...
- }
- //配置事件发布器
- public AuthenticationManagerBuilder authenticationEventPublisher(
- AuthenticationEventPublisher eventPublisher) {
- ...
- }
- //认证结束后是否删除密码凭证
- public AuthenticationManagerBuilder eraseCredentials(boolean eraseCredentials) {
- ...
- }
- //配置内存用户
- public InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder> inMemoryAuthentication()
- throws Exception {
- return apply(new InMemoryUserDetailsManagerConfigurer<>());
- }
- //配置数据库用户
- public JdbcUserDetailsManagerConfigurer<AuthenticationManagerBuilder> jdbcAuthentication()
- throws Exception {
- return apply(new JdbcUserDetailsManagerConfigurer<>());
- }
- //配置userDetailService
- public <T extends UserDetailsService> DaoAuthenticationConfigurer<AuthenticationManagerBuilder, T> userDetailsService(
- T userDetailsService) throws Exception {
- ...
- }
- //配置authenticationProvider
- public AuthenticationManagerBuilder authenticationProvider(
- AuthenticationProvider authenticationProvider) {
- this.authenticationProviders.add(authenticationProvider);
- return this;
- }
- }
具体根据实际情况进行配置,注意:UserDetailService会默认加载DaoAuthenticationProvider。
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.userDetailsService(jwtUserDetailsServiceImpl()).passwordEncoder(passwordEncoder());
- }
这里还要做一个说明,AuthenticationManagerBuilder有两种配置方式,一种是如上,还有一种是文章开头的配置,如果你的应用只有唯一一个WebSecurityConfigurerAdapter,那么他们之间的差距可以被忽略,从方法名可以看出两者的区别:使用@Autowired注入的AuthenticationManagerBuilder是全局的身份认证器,作用域可以跨越多个WebSecurityConfigurerAdapter,以及影响到基于Method的安全控制;而 protected configure()的方式则类似于一个匿名内部类,它的作用域局限于一个WebSecurityConfigurerAdapter内部。
我们可以配置多个HttpSecurity实例,就像我们可以有多个块. 关键在于对WebSecurityConfigurationAdapter进行多次扩展。例如下面是一个对/api/开头的URL进行的不同的设置。
- @EnableWebSecurity
- public class MultiHttpSecurityConfig {
- @Bean //<1>
- public UserDetailsService userDetailsService() throws Exception {
- // ensure the passwords are encoded properly
- UserBuilder users = User.withDefaultPasswordEncoder();
- InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
- manager.createUser(users.username("user").password("password").roles("USER").build());
- manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build());
- return manager;
- }
-
- @Configuration
- @Order(1) //<2>
- public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
- protected void configure(HttpSecurity http) throws Exception {
- http
- .antMatcher("/api/**") //<3>
- .authorizeRequests()
- .anyRequest().hasRole("ADMIN")
- .and()
- .httpBasic();
- }
- }
-
- @Configuration <4>
- public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .authorizeRequests()
- .anyRequest().authenticated()
- .and()
- .formLogin();
- }
- }
- }
<1> 配置正常的验证。
<2> 创建一个WebSecurityConfigurerAdapter,包含一个@Order注解,用来指定个哪一个WebSecurityConfigurerAdapter更优先。
<3> http.antMatcher指出,这个HttpSecurity只应用到以/api/开头的URL上。
<4> 创建另外一个WebSecurityConfigurerAdapter实例。用于不以/api/开头的URL,这个配置的顺序在ApiWebSecurityConfigurationAdapter之后,因为他没有指定@Order值为1(没有指定@Order默认会被放到最后).
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。