四、项目接入Security

概述

一组 filter 过滤器链组成的权限认证。

注入依赖

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

测试

在仅仅添加完依赖的情况下,启动项目看看:
控制台打印的密码
在这里插入图片描述
访问一下项目中的某个方法或页面:

http://localhost:8080/swagger-ui.html

他会自动跳转到security登录页面
在这里插入图片描述
在登陆 from 表单里输入如下:

    用户名:user
    密码:50ec3bbe-9177-4902-87fc-e7185497fc45(控制台打印的)

点击 Sign in请求可以正常通过
在这里插入图片描述

编写Security配置类(定义哪些URL需要被保护、哪些不需要被保护)

Spring Security比较重要的几个类

  • WebSecurityConfigurerAdapter:自定义Security策略,配置类需要继承这个类,实现其两个configure方法(认证和授权)
  • AuthenticationManagerBuilder:自定义认证策略
  • HttpSecurity:自定义授权策略
  • @EnableWebSecurity:开启WebSecurity模式
  • @EnableGlobalMethodSecurity:当我们想要开启spring方法级安全时,只需要在任何 @Configuration实例上使用 @EnableGlobalMethodSecurity 注解就能达到此目的。同时这个注解为我们提供了prePostEnabled 、securedEnabled 和 jsr250Enabled 三种不同的机制来实现同一种功能
    1)实际前后端分离开发时,并不是所有接口都需要授权,所以需要配置暴露一些接口或文档,对此修改一下配置条件
    2)实际开发中是不可能使用上方 Spring Security 默认的这种方式的,如何去覆盖掉 Spring Security 默认的配置呢?
package com.springboot.demo.config;

import org.springframework.context.annotation.Configuration;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author zihui
 * @version 1.0
 * @title: WebSecurityConfig
 * @description: TODO
 * @date 2021-01-18 10:52:16
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 认证
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication() // 项目启动 账户-密码-角色 信息保存进内存中
                .withUser("zhangsan").password("{noop}123456").roles("VIP1")
                .and().withUser("lisi").password("{noop}123456").roles("VIP2")
                .and().withUser("wangwu").password("{noop}123456").roles("VIP1", "VIP2");

        /*
          说明:
            1.这里采用的的是把用户角色保存在内存中,数据是写死的,当然数据可以从数据库中查出再写入内存中;
            2.随后定义的三个用户,没有用户定义了其用户名,密码和角色
            3.Security5默认要求密码使用加密,不加密的话就使用"{noop}123456"这样的写法,加密的话需要使用
                PasswordEncoder的实现类进行加密
         */
    }

    /**
     * 授权
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 禁止隧道(跨站防护)、禁止跨域、禁止头部
//        http.csrf().disable().cors().disable().headers().disable();
        http.csrf().disable();
        // 所有的人都可以访问的路径
        http.authorizeRequests()// 定义哪些URL需要被保护、哪些不需要被保护
//                .antMatchers(HttpMethod.OPTIONS).permitAll()    // 直接放过 OPTIONS 请求
//                .antMatchers("/**").permitAll()  // 不检查登录令牌,放行所有请求
                .antMatchers("/static/**", "/", "/csrf").permitAll()
                .antMatchers("/v2/api-docs","/swagger-ui.html","/webjars/**","/swagger-resources/**").permitAll()
                .antMatchers("/favicon.ico", "/actuator/**").permitAll()
                .antMatchers("/v2/**").permitAll()
                // VIP1的用户可以访问v1下的所有路径
                .antMatchers("/v1/test/hello").hasRole("VIP1")
                .anyRequest()// 任何请求,登录后可以访问
                .authenticated()
        ;

//        /*
//         开启自动配置的登录功能,如果没有登录就会来到登录页面
//            1. 会自动生成登录页面 /login
//            2. 登录失败会自动重定向到 /login?error
//         */
         http.formLogin()
//                 /*
//                自定义登录页面设置
//                    1. 登录的路径还是设置成/login,否则算是自定义登录路径,其他的设置也需要改变
//                       /login(get):到登录页,, 自定义的话就是 /authenticate(get)
//                       /login(post):登录检查,,自定义的话就是 /authenticate(post)
//                    2. 可以自定义form表达提交的参数名称
//                       默认username字段提交用户名,可以通过usernameParameter自定义
//                       默认password字段提交密码,可以用过passwordParameter自定义
//                    3. loginProcessingUrl("/xxx") 可以自定义登录成功后跳转的路径
//                 */
//             .loginPage("/login").loginProcessingUrl("/login/process")
        ;
//        /*
//         开启自动配置的退出功能:
//            1. 访问/logout请求,用户注销,清楚session
//            2. 注销成功后重定向到 login?logout,,可以通过logoutSuccessUrl("/")自定义
//         */
//        http.logout().logoutSuccessUrl("/");
    }
}

启动项目访问http://localhost:8080/swagger-ui.html#/,效果如下,不需要权限登录就可以访问API文档

访问接口时,因为该接口并未在忽略url中配置,发现返回的是一个html文件(其实是security自己的登录页面),但这个时候security默认启动生成的密钥已经不能实现登录功能
在这里插入图片描述
另开一个页面使用项目启动时保存在内存中的用户登录之后,这个页面的swaggerAPI就可以使用,有对应权限可查询,无对应权限的返回403(无资源)
在这里插入图片描述

Security如何优雅的接入swagger

点此传送门

自定义认证逻辑

从数据库进行用户认证

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值