Spring Security入门教程 通俗易懂 超详细 【内含案例】

Spring Security的简单使用

推荐 Java 常见面试题

简介

  • SSM 整合 Security 是比较麻烦的,虽然Security的功能比 Shiro 强大,相反却没有Shiro的使用量多
  • SpringBoot出现后简化了Spring系列的配置文件,因此SpringSecurity的使用逐渐增加

一、创建项目

查看代码

在 SpringBoot 中直接引入 Spring Security 依赖即可

image

创建项目的启动类

image

创建 SecurityController 类

image

  • 启动后访问 localhost:8080/hello
  • 会自动跳到 localhost:8080/login
  • 需要登录后才能访问 /hello

image

二、用户名配置

查看代码

  • 默认情况下用户名是 user ,而密码会在项目启动时 控制台 打印出一串随机 字符串,这就是密码.每次启动项目,密码都不一样

image

  • 对登录的用户名/密码进行配置,有三种不同的方式
  1. application 配置文件中声明
  2. java 代码配置在内存里
  3. 通过获取 数据库

第一种方式 application.yml 文件中

image

第二种方式 创建一个SecurityConfig配置类,继承 WebSecurityConfigurerAdapter

image

第三种方法没有进行演示,就是在数据库中取出usernamepassword配置到内存中

三、忽略拦截

查看代码

image

在配置类中重写 configure(WebSecurity web) 方法,然后直接访问即可

image

pom.xml文件

返回阅读


    org.springframework.boot
    spring-boot-starter-security



    org.springframework.boot
    spring-boot-starter-web

启动类文件
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@SpringBootApplication
public class SecurityApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecurityApplication.class, args);
    }
}
SecurityController 文件
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@RestController
public class SecurityController {

    /**
     * 不用登录就可访问
     * @return
     */
    @RequestMapping("/hi")
    public String sayHi(){
        return "Hi bro!";
    }

    @RequestMapping("/hello")
    public String sayHello(){
        return "Hello bro!";
    }
}
application.yml 配置文件

返回阅读

spring:
  security:
    user:
      name: beixuan
      password: beixuan
SecurityConfig Java配置文件

此方法配置用户与配置 yml 文件效果一致

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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author https://www.cnblogs.com/beixuan/
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        //Spring Security5之后 官方需要密码强制加密,如不想加密可创建一个过期的 PasswordEncoder 的实例 NoOpPasswordEncoder,但不安全
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode("beixuan");
        //添加一个用户[beixuan] 角色为[admin] 密码是[beixuan加密后的密钥]
        auth.inMemoryAuthentication()
                .withUser("beixuan")
                .roles("admin")
                .password(password);
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
  • 具体的登录配置 下面代码借鉴于 江南一点雨 随笔的代码,有兴趣可以看看
  • VerifyCodeFilter 一次性验证码,可以查看资料了解其使用方法,这里不再叙述
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    VerifyCodeFilter verifyCodeFilter;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(verifyCodeFilter, UsernamePasswordAuthenticationFilter.class);
        http
        .authorizeRequests()//开启登录配置
        .antMatchers("/hello").hasRole("admin")//表示访问 /hello 这个接口,需要具备 admin 这个角色
        .anyRequest().authenticated()//表示剩余的其他接口,登录之后就能访问
        .and()
        .formLogin()
        //定义登录页面,未登录时,访问一个需要登录之后才能访问的接口,会自动跳转到该页面
        .loginPage("/login_p")
        //登录处理接口
        .loginProcessingUrl("/doLogin")
        //定义登录时,用户名的 key,默认为 username
        .usernameParameter("uname")
        //定义登录时,用户密码的 key,默认为 password
        .passwordParameter("passwd")
        //登录成功的处理器
        .successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("success");
                    out.flush();
                }
            })
            .failureHandler(new AuthenticationFailureHandler() {
                @Override
                public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException exception) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("fail");
                    out.flush();
                }
            })
            .permitAll()//和表单登录相关的接口统统都直接通过
            .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessHandler(new LogoutSuccessHandler() {
                @Override
                public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                    resp.setContentType("application/json;charset=utf-8");
                    PrintWriter out = resp.getWriter();
                    out.write("logout success");
                    out.flush();
                }
            })
            .permitAll()
            .and()
            .httpBasic()
            .and()
            .csrf().disable();
    }
忽略拦截分两步

返回阅读

增加访问路径/hi

/**
 * 不用登录就可访问
 * @return
 */
@RequestMapping("/hi")
public String sayHi(){
    return "Hi bro!";
}

增加配置代码

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/hi");
}

即可不用登录访问/hi路径

END

本文就先说到这里,有问题欢迎留言讨论

你可能感兴趣的:(Spring Security入门教程 通俗易懂 超详细 【内含案例】)