SpringBoot集成Spring Security

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。

有两个作用:

  • 认证:验证用户名和密码是否合法(是否系统中用户),这是第一关;
  • 授权:是系统用户不代表你能使用某些功能,因为你可能没有权限,这是第二关;

Spring Security底层使用的是过滤器,针对url进行的拦截,对应到java中也就是类; 因此被称为粗粒度授权验证,就是验证url,你当前用户有没有这个url的权限。

1.新建一个springboot项目

 

 

2.引入Spring Security 依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

3.新建一个controller测试访问

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String index(){
        return "hello world!";
    }
}

4.运行项目:访问http://localhost:8080/hello

Spring Security默认给出用户名为user 密码为项目启动运行时生成的一串字符串如下图

 

当访问hello页面时,会默认跳转到login页面进行登录认证

 

 

认证成功会跳转到hello页面

 

 

5.Spring Security用户密码配置

1.springboot配置文件中添加配置

spring.security.user.name=admin
spring.security.user.password=123456

 2.java代码在内存中配置用户

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity  // 启用Spring Security的Web安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 将用户设置在内存中
     *
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void config(AuthenticationManagerBuilder auth) throws Exception {
        // 在内存中配置用户,配置多个用户调用`and()`方法
        auth.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder()) // 指定加密方式
                .withUser("admin").password(passwordEncoder().encode("123456")).roles("ADMIN")
                .and().withUser("test").password(passwordEncoder().encode("123456")).roles("USER");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // BCryptPasswordEncoder:Spring Security 提供的加密工具,可快速实现加密加盐
        return new BCryptPasswordEncoder();
    }

}

3.从数据库获取账号,密码信息

6.登录处理和忽略拦截

@Controller
public class IndexController {

    @GetMapping("/index")
    public String index(){
        return "hello world !";
    }

    @RequestMapping("login")
    public String showLogin(){
        return "login.html";
    }

    @GetMapping("/home")
    @ResponseBody
    public String home(){
        return "欢迎来到主页!";
    }
}

 

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 将用户设置在内存中
     *
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void config(AuthenticationManagerBuilder auth) throws Exception {
        // 在内存中配置用户,配置多个用户调用`and()`方法
        auth.inMemoryAuthentication()
                // 指定加密方式
                .passwordEncoder(passwordEncoder())
                .withUser("admin").password(passwordEncoder().encode("123456")).roles("ADMIN")
                .and()
                .withUser("test").password(passwordEncoder().encode("123456")).roles("USER");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // Spring Security 提供的密码加密工具,可快速实现加密加盐
        return new BCryptPasswordEncoder();
    }


    //登录配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开启登录配置
        http.authorizeRequests()
                // 标识访问 `/index` 这个接口,需要具备`ADMIN`角色
                .antMatchers("/index").hasRole("ADMIN")
                // 允许匿名的url - 可理解为放行接口 - 多个接口使用,分割
                .antMatchers("/", "/home").permitAll()
                // 其余所有请求都需要认证
                .anyRequest().authenticated()
                .and()
                // 设置登录认证页面
                .formLogin().loginPage("/login")
                // 登录成功后的处理接口 - 方式①
                .loginProcessingUrl("/home")
                // 自定义登陆用户名和密码属性名,默认为 username和password
                .usernameParameter("username")
                .passwordParameter("password")
                // 登录成功后的处理器  - 方式②
//                .successHandler((req, resp, authentication) -> {
//                    resp.setContentType("application/json;charset=utf-8");
//                    PrintWriter out = resp.getWriter();
//                    out.write("登录成功...");
//                    out.flush();
//                })
                // 配置登录失败的回调
                .failureHandler((req, resp, exception) -> {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("登录失败...");
                    out.flush();
                })
                .permitAll()//和表单登录相关的接口统统都直接通过
                .and()
                .logout().logoutUrl("/logout")
                // 配置注销成功的回调
                .logoutSuccessHandler((req, resp, authentication) -> {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("注销成功...");
                    out.flush();
                })
                .permitAll()
                .and()
                .httpBasic()
                .and()
                // 关闭CSRF跨域
                .csrf().disable();

    }

     //忽略拦截
    @Override
    public void configure(WebSecurity web) throws Exception {
        // 设置拦截忽略url - 会直接过滤该url - 将不会经过Spring Security过滤器链
        web.ignoring().antMatchers("/getUserInfo");
        // 设置拦截忽略文件夹,可以对静态资源放行
        web.ignoring().antMatchers("/css/**", "/js/**");
    }
}

 

posted @ 2019-11-16 10:47  海绵-宝宝  阅读(328)  评论(0编辑  收藏  举报