Spring Security(1)入门体验

Spring Security(1)入门体验


Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权。本片文章将讲述Security入门到项目实战使用。其中包括简单的登录和项目常用的权限管理,权限校验有两种方式、角色资源校验、URL校验,如果有一定基础的可以想找解决办法的可以直接跳过前面基础直接寻找自己需要的解答内容。

二者区别

  1. Spring Security:重量级安全框架
  2. Apache Shiro:轻量级安全框架
    关于shiro的权限认证与授权,(这个以后有需要再出一篇关于 Shiro 的内容)

SpringBoot集成Spring Security入门体验

基于Spring Boot 2.1.8

1、引入Spring Security依赖

<!--添加Spring securit依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2、新建一个controller 测试访问

@RestController
public class IndexController {
    @GetMapping("/index")
    public String index() {
        return "Hello World ~";
    }
}

3、运行项目访问:http://127.0.0.1:8080/index

温馨小提示:在不进行任何配置的情况下,Spring Security 给出的默认用户名为user 密码则是项目在启动运行时随机生成的一串字符串,会打印在控制台,如下图:




当我们访问index首页的时候,系统会默认跳转到login页面进行登录认证




认证成功之后才会跳转到我们的index页面





用户密码配置

除了上面Spring Security在不进行任何配置下默认给出的用户user 密码随项目启动生成随机字符串,我们还可以通过以下方式配置

1、springboot配置文件中配置

spring:
 security:
   user:
     name: admin  # 用户名
     password: 123456  # 密码

2、java代码在内存中配置

新建 Security 核心配置类继承 WebSecurityConfigurerAdapter

@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、从数据库中获取用户账号、密码信息

往往实际使用中会比上述情况复杂很多。
(动态添加用户,绑定角色,角色绑定权限资源等),这个留到文章后面鉴权内容再说。

登录处理 与 忽略拦截

最常用的简单配置,相关代码都有注释相信很容易理解

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
   /**
    * 登录处理
    * @param http
    * @throws Exception
    */
   @Override
   protected void configure(HttpSecurity http) throws Exception {
       
       //==========================================路径相关配置start
       
       // antMatcher():配置需要处理的URL  authorizeRequests():为URL配置授权事项,例如是否需要进行身份验证或仅某些角色可以访问它等
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.antMatcher("/**").authorizeRequests();
       
       // 标记只能在 服务器本地ip[127.0.0.1或者localhost] 访问`/home`接口,其他ip地址无法访问
        registry.antMatchers("/home").hasIpAddress("127.0.0.1");

        // 标识访问 `/index` 这个接口,需要具备`ADMIN`角色
        registry.antMatchers("/index").hasRole("ADMIN");

        // 允许匿名的url - 可理解为方形接口 - 多个接口使用,分割
        registry.antMatchers("/login", "/index").permitAll();

        // OPTIONS(选项):查找适用于一个特定网址资源的通讯选择。 在不需执行具体的涉及数据传输的动作情况下, 允许客户端来确定与资源相关的选项以及 / 或者要求, 或是一个服务器的性能
        registry.antMatchers(HttpMethod.OPTIONS, "/**").denyAll();

        // 其余所有请求都需要认证
        registry.anyRequest().authenticated();
       
       //==========================================路径相关配置end
       
       // 禁用CSRF 开启跨域
        http.csrf().disable().cors();

        //配置HTTP基本身份认证
        http.httpBasic();
       
       // 设置登录认证页面
       http.formLogin().loginPage("/login")
           // 登录后的处理接口 - 方式①
           .loginProcessingUrl("/user/login")
           // 自定义登陆用户名和密码属性名,默认为 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();
           })
           .logout().logoutUrl("/logout")
           // 配置注销成功的回调
           .logoutSuccessHandler((req, resp, authentication) -> {
               resp.setContentType("application/json;charset=utf-8");
               PrintWriter out = resp.getWriter();
               out.write("注销成功...");
               out.flush();
           })
           // 和表单登录相关的接口都通过
           .permitAll()
   }
   /**
    * 忽略拦截
    * @param web
    * @throws Exception
    */
   @Override
   public void configure(WebSecurity web) throws Exception {
       // 设置拦截忽略url - 会直接过滤该url - 将不会经过Spring Security过滤器
       web.ignoring().antMatchers("/getUserInfo");
       // 设置拦截忽略文件夹,可以对静态资源放行
       web.ignoring().antMatchers("/css/**", "/js/**");
   }
}






参考文献以及版权声明:

1、Spring Security(1) 入门体验 作者:郑清 采用协议:CC 4.0 BY-SA
原文链接:https://blog.csdn.net/qq_38225558/article/details/101754743

posted @ 2020-07-05 13:24  KeZP  阅读(308)  评论(0)    收藏  举报