SpringSecurity(1-security入门-基于内存+角色方式的认证和授权的学习)

本文介绍了Spring Security的基本概念,通过一个Spring Cloud工程展示了如何配置和使用Spring Security进行认证和授权。文章详细阐述了不同场景下的测试步骤,包括不同角色访问特定接口的情况,并讨论了在遇到403权限错误时的解决方法,如添加配置或处理CSRF问题。
摘要由CSDN通过智能技术生成

一:什么是Spring Security
Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。提供了完善的认证机制和方法级的授权功能。是一款非常优秀的权限管理框架。它的核心是一组过滤器链,不同的功能经由不同的过滤器。

二:认证授权功能实现

1,准备一个springCloud的工程,引入oAuth2的依赖

<!-- oAuth2 -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-oauth2</artifactId>
	<version>2.0.2.RELEASE</version>
</dependency>

2,创建基于内存认证/授权配置类

@EnableWebSecurity
@Configuration
public class webSecurityConfig extends WebSecurityConfigurerAdapter {
    //密码编译比对方式
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    //访问路径配置
    @Override
    protected void configure(HttpSecurity http) throws java.lang.Exception {
		//.hasAuthority : 基于资源授权  .hasRole:基于角色授权
        http.authorizeRequests()
        .antMatchers("/auth/hello").hasRole("GUEST")   //给访问的地址加上角色限制,只有指定的角色才能访问
        .antMatchers("/auth/home").hasRole("USER")
        .antMatchers("/auth/admin").hasRole("ADMIN")

        .antMatchers("/test/health").permitAll()     //此路径不需要经过过认证,可以不登录直接请求
        .anyRequest().authenticated()                             //除配置的/test/health路径其他请求都需要认证
        .and()
        .formLogin() //允许表单登陆
                .successForwardUrl("/sys/login");  //自定义表单登陆成功后的跳转路径
    }

    //基于内存的用户配置
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws java.lang.Exception {
        //创建三个用户到内存中,并给他们分配角色
        auth.inMemoryAuthentication()
                .withUser("zhangsan").password(this.passwordEncoder().encode("123456")).roles("GUEST");
        auth.inMemoryAuthentication()
                .withUser("lisi").password(this.passwordEncoder().encode("123456")).roles("USER");
        auth.inMemoryAuthentication()
                .withUser("wangwu").password(this.passwordEncoder().encode("123456")).roles("USER","ADMIN");
    }
}

要访问测试的接口

@GetMapping("/auth/hello")
    @ResponseBody
    public String test1(){
        logger.info("+++++++++++++++++++++++++++++++请求成功TEST_GUEST+++++++++++++++++++++++++++++++++++");
        return "GUEST";
    }
    @GetMapping("/auth/home")
    @ResponseBody
    public String test2(){
        logger.info("+++++++++++++++++++++++++++++++请求成功TEST_USER+++++++++++++++++++++++++++++++++++");
        return "USER";
    }
    @GetMapping("/auth/admin")
    @ResponseBody
    public String test3(){
        logger.info("+++++++++++++++++++++++++++++++请求成功TEST_ADMIN+++++++++++++++++++++++++++++++++++");
        return "ADMIN";
    }

    @RequestMapping("/sys/login")
    @ResponseBody
    public String test4(){
        logger.info("+++++++++++++++++++++++++++++++请求成功TEST_SYS_LOGIN+++++++++++++++++++++++++++++++++++");
        return "登陆成功TESDT";
    }

    @GetMapping("/test/health")
    @ResponseBody
    public String test5(){
        logger.info("+++++++++++++++++++++++++++++++—健康检查—TEST+++++++++++++++++++++++++++++++++++");
        return "健康检查";
    }

3,启动项目,并访问 http://localhost:9901/login (不唯一) ,出现登陆页面就说明该工程具备oAuth2的功能了
在这里插入图片描述
三:测试:

场景一:登陆zhangsan(角色:GUEST),然后访问 /auth/hello 路径(该路径配置的角色:GUEST),人物角色和路径角色一致,那么能调通测试接口

步骤一:登陆:
在这里插入图片描述
步骤二:登陆成功,返回自定义接口内容
在这里插入图片描述
步骤三:访问 /auth/hello 的接口,浏览器输入 http://localhost:9901/auth/hello 得到了接口返回的字符串
在这里插入图片描述
场景二:登陆zhangsan(角色:GUEST),然后访问 /auth/admin 路径(该路径配置的角色:ADMIN),人物角色和路径角色不一致,那么不能调通测试接口

步骤一:场景一zhangsan已经登陆这里直接访问 http://localhost:9901/auth/admin
,由于该路径没有GUEST权限,故接口访问不成功
在这里插入图片描述
场景三:登陆wangwu(角色:User,ADMIN),然后访问 /auth/home(配置的USER角色) 和 /auth/admin(配置的ADMIN角色) 路径(,人物角色和路径角色一致,那么两个接口都能访问成功

步骤一:登陆
在这里插入图片描述
步骤二:登陆成功
在这里插入图片描述
步骤三:访问 /auth/home/auth/admin接口浏览器输入 http://localhost:9901/auth/home 和 http://localhost:9901/auth/admin 都访问成功了
在这里插入图片描述
在这里插入图片描述
步骤四:访问/auth/hello接口,这个接口是GUEST权限的wangwu是没有的,浏览器输入http://localhost:9901/auth/hello 报错
在这里插入图片描述

问题回顾
在上面的配置类里面,虽然配置了有的路径可以不经过验证,但是访问的时候还是会报错403,没有权限,原因时应为接口请方式为post方式,而SpringSecurity为防止CSRF(跨站请求伪造)为拦截出get请求以外的大多数请求方式,

解决方式一:

加上 .csrf().disable() 的配置

//访问路径配置
    @Override
    protected void configure(HttpSecurity http) throws java.lang.Exception {

        http
        .csrf().disable() //去除csrf攻击的配置,以便除get请求方式,其他请求方式也能访问接口
        .authorizeRequests()
        .antMatchers("/auth/hello").hasRole("GUEST")   //给访问的地址加上角色限制,只有指定的角色才能访问
        .antMatchers("/auth/home").hasRole("USER")
        .antMatchers("/auth/admin").hasRole("ADMIN")

        .antMatchers("/test/health").permitAll()     //此路径不需要经过过认证,可以不登录直接请求
        .anyRequest().authenticated()                             //除配置的/test/health路径其他请求都需要认证
        .and()
        .formLogin() //允许表单登陆
                .successForwardUrl("/sys/login");  //自定义表单登陆成功后的跳转路径
    }

解决方式二:
前端加上csrf的配置
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值