那么如何才能正确的掌握Redis呢?

为了让大家能够在Redis上能够加深,所以这次给大家准备了一些Redis的学习资料,还有一些大厂的面试题,包括以下这些面试题

  • 并发编程面试题汇总
  • JVM面试题汇总
  • Netty常被问到的那些面试题汇总
  • Tomcat面试题整理汇总
  • Mysql面试题汇总
  • Spring源码深度解析
  • Mybatis常见面试题汇总
  • Nginx那些面试题汇总
  • Zookeeper面试题汇总
  • RabbitMQ常见面试题汇总

JVM常频面试:

springboot 部分接口取消鉴权 springboot对外接口鉴权_面试

Mysql面试题汇总(一)

springboot 部分接口取消鉴权 springboot对外接口鉴权_spring_02

Mysql面试题汇总(二)

springboot 部分接口取消鉴权 springboot对外接口鉴权_面试_03

Redis常见面试题汇总(300+题)

springboot 部分接口取消鉴权 springboot对外接口鉴权_面试_04

重点:
1、将自定义的安全配置类对象注入到Spring容器中;
2、构建WebSecurity对象

说明:
1、获取安全配置,通过@value的方式实现了AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers();
2、获取类型为WebSecurityConfigurer类及其子类匹配的bean,包括WebSecurityConfigurerAdapter、继承WebSecurityConfigurerAdapter的自定义安全配置类

1)、通过@value(“#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}”)获取安全配置
2)、调用org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()

@Autowired(required = false)
	public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> objectPostProcessor,
			@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
			throws Exception {
		this.webSecurity = objectPostProcessor.postProcess(new WebSecurity(objectPostProcessor));
		if (this.debugEnabled != null) {
			this.webSecurity.debug(this.debugEnabled);
		}
		webSecurityConfigurers.sort(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) {
			this.webSecurity.apply(webSecurityConfigurer);
		}
		this.webSecurityConfigurers = webSecurityConfigurers;
	}
3.2、springSecurityFilterChain方法

说明:

1、通过@Bean将springSecurityFilterChain()方法构建的Filter实例对象按名称为springSecurityFilterChain的Bean注入到Spring容器中
2、WebSecurity.build方法会启动对象的配置,重点是: 【可以调用到自定义安全配置类的配置方法】实现自定义配置认证退出处理类、不用认证url等SpringBoot Security安全配置

@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT\_FILTER\_NAME)
public Filter springSecurityFilterChain() throws Exception {
	boolean hasConfigurers = this.webSecurityConfigurers != null && !this.webSecurityConfigurers.isEmpty();
	boolean hasFilterChain = !this.securityFilterChains.isEmpty();
	Assert.state(!(hasConfigurers && hasFilterChain),
				"Found WebSecurityConfigurerAdapter as well as SecurityFilterChain. Please select just one.");
	if (!hasConfigurers && !hasFilterChain) {
		WebSecurityConfigurerAdapter adapter = this.objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
		});
		this.webSecurity.apply(adapter);
	}
	for (SecurityFilterChain securityFilterChain : this.securityFilterChains) {
		this.webSecurity.addSecurityFilterChainBuilder(() -> securityFilterChain);
		for (Filter filter : securityFilterChain.getFilters()) {
			if (filter instanceof FilterSecurityInterceptor) {
				this.webSecurity.securityInterceptor((FilterSecurityInterceptor) filter);
				break;
			}
		}
	}
	for (WebSecurityCustomizer customizer : this.webSecurityCustomizers) {
		customizer.customize(this.webSecurity);
	}
	return this.webSecurity.build();
}

4、自定义安全配置类

自定义安全配置类继承WebSecurityConfigurerAdapter,以对象名为authenticationManager的bean将AuthenticationManager对象注入到Spring容器中

springboot 部分接口取消鉴权 springboot对外接口鉴权_学习_05

《authenticationManager的bean对象注入流程源码分析图》

说明:

1、以@Bean的方式将AuthenticationManager的Bean以Id="authenticationManager"注入到Spring容器中;
2、调用父类WebSecurityConfigurerAdapter的authenticationManagerBean()方法

重点: 通过authenticationManagerBean()方法实现了将ProviderManager对象做为AuthenticationManager的实例对象,参照 第二章节->2、调用Spring Security安全认证方法中的《将ProviderManager对象做为authenticationManager的bean对象流程源码分析图》

自定义安全配置类源码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter;
import cn.edu.tit.ipaddress.ms.framework.config.properties.PermitAllUrlProperties;
import cn.edu.tit.ipaddress.ms.framework.security.filter.JwtAuthenticationTokenFilter;
import cn.edu.tit.ipaddress.ms.framework.security.handle.AuthenticationEntryPointImpl;
import cn.edu.tit.ipaddress.ms.framework.security.handle.LogoutSuccessHandlerImpl;

/\*\*
 \* spring security配置
 \* 
 \* @author ruoyi
 \*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{
    /\*\*
 \* 自定义用户认证逻辑
 \*/
    @Autowired
    private UserDetailsService userDetailsService;
    
    /\*\*
 \* 认证失败处理类
 \*/
    @Autowired
    private AuthenticationEntryPointImpl unauthorizedHandler;

    /\*\*
 \* 退出处理类
 \*/
    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    /\*\*
 \* token认证过滤器
 \*/
    @Autowired
    private JwtAuthenticationTokenFilter authenticationTokenFilter;
    
    /\*\*
 \* 跨域过滤器
 \*/
    @Autowired
    private CorsFilter corsFilter;

    /\*\*
 \* 允许匿名访问的地址
 \*/
    @Autowired
    private PermitAllUrlProperties permitAllUrl;

    /\*\*
 \* 解决 无法直接注入 AuthenticationManager
 \*
 \* @return
 \* @throws Exception
 \*/
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception
    {
        return super.authenticationManagerBean();
    }

    /\*\*
 \* anyRequest | 匹配所有请求路径
 \* access | SpringEl表达式结果为true时可以访问
 \* anonymous | 匿名可以访问
 \* denyAll | 用户不能访问
 \* fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
 \* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
 \* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
 \* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
 \* hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
 \* hasRole | 如果有参数,参数表示角色,则其角色可以访问
 \* permitAll | 用户可以任意访问
 \* rememberMe | 允许通过remember-me登录的用户访问
 \* authenticated | 用户登录后可访问
 \*/
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        // 注解标记允许匿名访问的url
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests();
        permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll());

        httpSecurity
                // CSRF禁用,因为不使用session
                .csrf().disable()
                // 禁用HTTP响应标头
                .headers().cacheControl().disable().and()
                // 认证失败处理类
                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
                // 基于token,所以不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                // 过滤请求
                .authorizeRequests()
                // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                .antMatchers("/login","/loginWeixin","/register", "/captchaImage").permitAll()
                // 静态资源,可匿名访问
                .antMatchers(HttpMethod.GET, "/", "/\*.html", "/\*\*/\*.html", "/\*\*/\*.css", "/\*\*/\*.js", "/profile/\*\*").permitAll()
                .antMatchers("/swagger-ui.html", "/swagger-resources/\*\*", "/webjars/\*\*", "/\*/api-docs", "/druid/\*\*").permitAll()
                // 除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated()
                .and()
                .headers().frameOptions().disable();
        // 添加Logout filter
        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
        // 添加JWT filter
        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
        // 添加CORS filter
        httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
    }

    /\*\*
 \* 强散列哈希加密实现
 \*/
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder()
    {
        return new BCryptPasswordEncoder();
    }

    /\*\*
 \* 身份认证接口
 \*/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception
    {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }
}

二、SpringBoot Security认证流程

1、在用户登录认证类中自动注入AuthenticationManager对象

自动注入AuthenticationManager对象

@Resource
private AuthenticationManager authenticationManager;

@Resource注解-说明:

一、@Resource和@Autowired异同
@Resoutce注解的功能和@Autowired相似的,可以互相替换,一般情况是可以正常运行的,由> @Resource标注的属性也会进行自动装配

二、二者区别:
1.提供者不同:
@AutoWired是Spring提供的
@Resource是由Java提供的

2.注入规则不同:
原则上@Autowired注入规则为“byType”(通过类型注入)