Security 认证授权入门教程(非常详细)

Security 认证授权入门教程


简单阐述一下基本的名词:

  • 认证保护服务器的内部资源被合理的请求,只允许那些合理(服务器校验过请求者的身份)能访问,而没有校验过的校验不通过的请求无法访问。
  • 授权:请求认证成功后,用来判断该请求是否有权限进行该项工作

单独基于Security作为权限管理框架

Spring Security的基本原理是过滤链,不同的过滤器过滤不同的操作,多个过滤器分工合作组成一套较为完整便与扩展的权限框架(有兴趣的同学可以自己去深入了解)

  1. maven依赖(Spring 相关的自己加入)
	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
	</dependency>
  1. 配置 SpringWebSecurityConfigurerAdapter 全局配置中心 大部分中心设置都在里面,(注释写的很详细)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true) //开启权限注解
public class SpringWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {


//    配置一个密码加密的算法类 我不太喜欢这么复杂的
//    @Bean
//    public BCryptPasswordEncoder encoder() {
//        return new BCryptPasswordEncoder();
//    }
	
	//自己手写了一个密码加密算法,其实没有具体加密功能,但是不写会报错 高版本的security强制要求
    @Bean
    public PasswordEncoder getPasswordEncoder(){
        PasswordEncoder passwordEncoder = new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
				//密码加密方式
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
				//返回判断用户输入值,和后台校验值是否一致 ,如果此处选择返回true 则用户 密码输入不正确也是可以认证通过
                return charSequence.equals(s);
            }
        };

        return passwordEncoder;
    }
	
	//自定义用户详情获取类
    @Autowired
    private  SpringUserDetailsService springUserDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//   这里是配置初始的用户密码以及对应的角色和权限 
//        auth.inMemoryAuthentication() //基于内存管理
//                .passwordEncoder(encoder()) //密码加密方式
//                .withUser("user_1").password("123456").roles("USER") 
//                .and()
//                .withUser("user_2").password("123456").roles("ADMIN").authorities("P1"); //配置用户2 相比用户1多了权限
 
		//设置本地自己实现的用户详情获取对象
        auth.userDetailsService(springUserDetailsService).passwordEncoder(getPasswordEncoder()); 
		//        auth.authenticationProvider() 该方式是设置本地的 用户密码实现 这个优先级比上面那个高,一旦设置了这个 上面那个不在生效

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        
//        http.csrf().disable() //关闭CSRF
//                .requestMatchers()             
//                //.antMatchers("/oauth/authorize")
//               .antMatchers("/index").and().authorizeRequests()///index 需要认证才能访问
//                .anyRequest().authenticated() //任何请求都要认证
//                .and()
//                .formLogin().permitAll(); // 登录接口 完全公开
        
		 http.authorizeRequests().anyRequest().authenticated() //任何请求都需要认证
                .and().formLogin().permitAll() //表单登录完全公开
                .and().logout().permitAll() //退出公开
                .and().csrf().disable(); //关闭 CSRF

    }
	

}
  1. 配置自定义的用户详情获取类 SpringUserDetailsService 用来获取到对应的用户信息。然后返回回去给后面的过滤器使用
@Service
public class SpringUserDetailsService implements UserDetailsService {
	
	//该类只有这一个方法 根据用户名获取用户信息,
	//返回的User对象是security自带的对象,第一个参数对象是用户名,第二个是密码,最后一个是权限集合
	//如果这里推荐去数据库查询 将结果返回,这里就不展示了。推崇精简
	//当用户名称不正确或其他原因可 直接throw UsernameNotFoundException("原因")
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
    //传入的s 就是用户名
    //LIST 是用户所具备的权限,正规做法是去数据库查询。这里是测试 只添加了一个ROLE_GGG的权限
        List<GrantedAuthority> list = new LinkedList();
        list.add(new SimpleGrantedAuthority("ROLE_GGG"));
        return new User("222","333",list);
        //这个写法是这要用户密码栏填写的密码是 333 就能通过验证
        //这里的333是我们预测的用户密码,至于校验密码是否正确交由PasswordEncoder.matchesf方法完成
    }
}

  1. 编写需要保护的方法 ,只要在受保护的方法上面加注解
@RestController
public class SpringExampleController {

    @GetMapping("/test")
    @PreAuthorize("hasAuthority('ROLE_GGG2')") //请求该方法需要拥有权限 ROLE_GGG2
//    @PreAuthorize("hasAuthority('ROLE_GGG')") //同上
    public String test(){
        //当前请求的用户信息,包含了账户密码,权限信息,IP地址等 在业务层任何地方皆可调用
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        return "this is test";
    }
}

测试

  1. 首先先尝试直接访问受保护的地址(任意就好了)

在这里插入图片描述

  1. 由于没有登录自动跳转到登录页面,security提供的默认登录页面,更具这个特殊的UserDetailsService,随便填写用户名,密码填写333 就能正确登录。
    在这里插入图片描述

  2. 由于没有该页面所以报404 但是认证是通过了在这里插入图片描述

  3. 该方式是基于Session方式认证不太安全。 在这里插入图片描述

  4. 访问 /test 直接显示没有权限 报403,关闭对应的注解,或者获取用户权限的时候多加权限即可解决
    在这里插入图片描述

总结:以上都是基于security自带的认证和授权。其中我们只需要负责将用户数据进行填充,和负责管理受保护的资源的权限需求,具体的授权校验和 认证校验security完成,如果你的业务特别复杂/想要深入了解 可以看 AuthenticationProvider(实际完成认证的接口)以及 AccessDecisionManager (默认的实际授权类,认证之后能不能访问受保护的资源全看他了)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值