• 配置类SecurityConfiguration
  • 只要使用spring security都要有这样一个配置类(如果是类配置的话),继承WebSecurityConfigurerAdapter
  • 主要实现两个方法configure(AuthenticationManagerBuilder auth)configure(HttpSecurity http)
  1. AuthenticationManagerBuilder 主要配置身份认证来源,也就是用户及其角色。

  2. HttpSecurity 主要配置路径,也就是资源的访问权限(是否需要认证,需要什么角色等)。

配置SecurityConfig

  • 继承 WebSecurityConfigurerAdapter 抽象类,实现 Spring Security 在 Web 场景下的自定义配置

重写configure(AuthenticationManagerBuilder auth) 想要在 WebSecurityConfigurerAdapter 中进行认证相关的配置,可以使用 configure(AuthenticationManagerBuilder auth) 暴露一个 AuthenticationManager 的建造器:AuthenticationManagerBuilder 如下所示:

// SecurityConfig.java
// 登录认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.
            // <X> 使用内存中的 InMemoryUserDetailsManager
            inMemoryAuthentication()
            // <Y> 不使用 PasswordEncoder 密码编码器
            .passwordEncoder(NoOpPasswordEncoder.getInstance())
            // <Z> 配置 admin 用户
            .withUser("admin").password("admin").roles("ADMIN")
            // <Z> 配置 normal 用户
            .and().withUser("normal").password("normal").roles("NORMAL");
}

  • AuthenticationManagerBuilder#inMemoryAuthentication() 方法,使用内存级别的 InMemoryUserDetailsManager Bean 对象,提供认证的用户信息。

  • Spring 内置了两种 UserDetailsManager 实现:

    • InMemoryUserDetailsManager
    • JdbcUserDetailsManager ,基于 JDBC的 JdbcUserDetailsManager 。
  • 实际项目中,我们更多采用调用AuthenticationManagerBuilder#userDetailsService(userDetailsService) 方法,使用自定义实现的 UserDetailsService 实现类,更加灵活、自由地实现认证的用户信息的读取。

  • 重写configure(HttpSecurity http) 配置 URL 的权限控制。

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("test/demo").permitAll()
                // 配置请求地址的权限
                .antMatchers("test/admin").hasRole("ADMIN")
                .antMatchers("test/normal").hasRole("NORMAL")
                .anyRequest().authenticated()
                // 设置 Form 表单登陆
                .and().formLogin()
            	//loginPage("/login")
            	.permitAll()
                .and().logout()
            	//logoutUrl("/logout")
            	.permitAll();
    }

  • authorizeRequests() 配置路径拦截,表明路径访问所对应的权限,角色,认证信息。
  • formLogin() 对应表单认证相关的配置
  • logout() 对应了注销相关的配置
  • httpBasic() 可以配置 basic 登录
    • 调用 HttpSecurity.authorizeRequests() 方法,开始配置 URL 的权限控制
  • 【常用】permitAll() 方法,所有用户可访问。

  • 【常用】denyAll() 方法,所有用户不可访问。

  • 【常用】authenticated() 方法,登录用户可访问。

    • anonymous() 方法,无需登录,即匿名用户可访问。
    • rememberMe() 方法,通过 remember me 登录的用户可访问。
    • fullyAuthenticated() 方法,非 remember me 登录的用户可访问。
    • hasIpAddress(String ipaddressExpression) 方法,来自指定 IP 表达式的用户可访问。
  • 【常用】hasRole(String role) 方法, 拥有指定角色的用户可访问。

  • 【常用】hasAnyRole(String... roles) 方法,拥有指定任一角色的用户可访问。

  • 【常用】hasAuthority(String authority) 方法,拥有指定权限(authority)的用户可访问。

  • 【常用】hasAuthority(String... authorities) 方法,拥有指定任一权限(authority)的用户可访问。

  • 【最牛】access(String attribute) 方法,当 Spring EL 表达式的执行结果为 true 时,可以访问。

@PermitAll 注解,等价于 permitAll() 方法,所有用户可访问。

  • 重要!!!因为在SecurityConfig中,配置了 .anyRequest().authenticated() ,任何请求,访问的用户都需要经过认证。所以这里 @PermitAll 注解实际是不生效的。

也就是说,Java Config 配置的权限,和注解配置的权限,两者是叠加的。

anyRequest

  • anyRequest() :在之前认证过程中我们就已经使用过 anyRequest(),表示匹配所有的请求。一般情况下此方法都会使用,设置全 部内容都需要进行认证。

antMatcher

public C antMatchers(String... antPatterns)

  • 需要放行所有静态资源,下面演示放行 js 文件夹下所有脚本文件。

.antMatchers("/js/**","/css/**").permitAll()

还有一种配置方式是只要是.js文件都将被放行

.antMatchers("/**/*.js").permitAll()

regexMatchers

  • 使用正则表达式进行匹配。和 antMatchers() 主要的区别就是参数, antMatchers() 参数是 ant 表达式, regexMatchers() 参数是正则表达式。 演示所有以.js 结尾的文件都被放行。

.regexMatchers( ".+[.]js").permitAll()

mvcMatchers

  • mvcMatchers()适用于配置了 servletPath 的情况。
  • 在Spring Security的配置类中配置 .servletPath() mvcMatchers()返回值特有的方法,antMatchers()regexMatchers()没有这个方法。在servletPath()中配置了 servletPath 后,mvcMatchers()直接写 SpringMVC 中@RequestMapping()中设置的路径即可。

    • .mvcMatchers("/demo").servletPath("/xxxx").permitAll()
  • 如果不习惯使用 mvcMatchers()也可以使用 antMatchers(),下面代码和上面代码是等效

    • .antMatchers("/xxxx/demo").permitAll()
  • 也可以使用 antMatchers(),下面代码和上面代码是等效

    • .antMatchers("/xxxx/demo").permitAll()