Spring-Security(权限)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dtttyc/article/details/88950201

前言

分享一波权限知识 ~ ,Who可以对What进行How的访问操作

Spring Security 是什么 ?

  1. Security是安全的意思
  2. Spring Security 是提供安全的框架
  3. 她是基于Servlet过滤器,IOC和AOP
  4. 他的主要作用就是为了web请求和访问提供了身份确认和授权处理, 避免了很多重复性代码,减少了业务逻辑, 直接调用ApI就可以

在这里插入图片描述

为什么使用Security ?

轻松扩展并且满足自定义要求
api方便

实现登陆拦截器

Security组件

  • SecurityContextHolder: 提供对SecurityContext 的访问
  • SecurityContext 持有Authentication 对象和其他可能需要的信息
  • AuthenticationManager 其中可以包含多个AuthenticationProvider
  • ProviderManager对象为AuthenticationManager接口的实现类
  • AuthenticationProvider 主要用来进行认证操作的类 调用其中的authenticate()方法去进行认证操作
  • Authentication:Spring Security方式的认证主体
  • GrantedAuthority:对认证主题的应用层面的授权,含当前用户的权限信息,通常使用角色表示
  • UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
  • UserDetailsService:通过username构建UserDetails对象,通过loadUserByUsername根据userName获取UserDetail对象 (可以在这里基于自身业务进行自定义的实现 如通过数据库,xml,缓存获取等)

步骤

  1. 引入pom文件
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-security</artifactId>
    </dependency>

在这个过程中我遇到一个小问题,springboot项目启动的时候,发现启动之后自动停止运行,真的是郁闷了, 最后发现是自己没有在pom文件加入web pom文件,警告一下自己吧~

	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
  1. 创建 SpringSecurityConfig 继承WebSecurityConfigurerAdapter
    重新config方法

表示拦截js和css和images

 @Override
    public void configure(WebSecurity web) throws Exception {
       web.ignoring().antMatchers("/js/**","/css/**","/images/**");
    }

对用户进行验证

   /**
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //定义的简单规则
        http.authorizeRequests()
        //路径所有./
                .antMatchers("/").permitAll()
                //被认证
                .anyRequest().authenticated()
                .and()
                //运行进行表单认证
                .logout().permitAll()
                .and()
                .formLogin();
        //关闭csrf的认证
        http.csrf().disable();
    }

```js
请求检测
@RestController
@EnableAutoConfiguration
public class DemoApplication {
@RequestMapping("/hello")
	public String hello(){
		return "hello word";
	}
}
	@RequestMapping("/hello")
	public String hello(){
		return "hello word";
	}

在这里插入图片描述

当访问localhost:8080/hello 的时候她会直接让你调到login登陆

在这里插入图片描述

权限分配

通过上面的描述我们知道spring Security api实现了拦截必须登录才可以访问, 假如我们现在根据不同用户有访问接口的不同权限,这个时候如何?

请求的方法上加上@PreAuthorize , 当角色为admin的时候才可以访问api roleAuth ,否则不可以访问

//这句话的意思是启用@PreAuthorize 这个注解,在启动类上面加上
@EnableGlobalMethodSecurity(prePostEnabled = true)
 //表示告诉应用与那个权限
	@PreAuthorize("hasRole('ROLE_ADMIN')")
	@RequestMapping("/roleAuth")
	public String roleAuth(){
		return "admin role";
	}

需要说明的是我们必须在前缀上加上Role

public class RoleVoter implements AccessDecisionVoter<Object> {
    private String rolePrefix = "ROLE_";

有两个角色,一个admin一个user

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin").password("123456").roles("ADMIN");
    auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin1").password("123456").roles("ADMIN");
    auth.inMemoryAuthentication().passwordEncoder(new MypasswordEncoder()).withUser("admin2").password("123456").roles("USER");

    }

如果这个时候我们跟数据库打交道

@Component
public class MyUserService  implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return null;
    }
}

MD5加密密码

为了安全我们要对密码进行加密,创建类MypasswordEncoder, 实现接口 PasswordEncoder

  /**
     * 加密方法,表示对原始密码进行加密
     * @param charSequence
     * @return
     */
    @Override
    public String encode(CharSequence charSequence) {
        Md5PasswordEncoder md5PasswordEncoder = new Md5PasswordEncoder();
        return md5PasswordEncoder.encodePassword(charSequence.toString(),"123456");
    }

    /**
     * 匹配方法
     * @param charSequence
     * @param s
     * @return
     */
    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return s.equals(charSequence.toString());
    }

具体的方法myUserService

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 表示登陆的时候使用那个做个类去做关于数据库方法的权限
        auth.userDetailsService(myUserService).passwordEncoder(new MypasswordEncoder());
    }

注解

// 方法执行之后做权限认证
	@PostAuthorize("hasRole()")
	@PreFilter和@PostFilter可以对集合类型的参数或返回值进行过滤, @preFilter表示针对那个参数, @postFilter表示针对当前返回的对象

security 劣势

  1. 不太容易控制, 虽然写起来可以调用别人的api
  2. 需要使用注解来控制

猜你喜欢

转载自blog.csdn.net/dtttyc/article/details/88950201