Java安全——一步步搭建Spring Security环境

首先,先创建springboot项目(这里我的版本号采用的是spring boot2.0),选择引入web和security的依赖

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

现在,我们创建一个Controller类作为接口进行测试:

@RestController
public class DemoController{
    @GetMapping("/")
    public String home(){
        return "hello hdonghong~";
    }
}

启动Spring Boot项目后,进行访问,当页面自动跳转到/login下面时说明security的环境已经搭建成功:
这里写图片描述

接下来,我们正式进行Spring Security的配置。
在刚刚创建的Controller类中增加一个接口test:

@GetMapping("/test")
    public String test(){
    return "test authentication";
}

然后创建SpringSecurityConfig类并继承WebSecurityConfigurerAdapter类,具体实现如下:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception{
        //允许访问项目主路径/的请求
        //其它请求都要经过拦截验证
        //同时也允许注销请求
        //支持表单验证登录
        //取消掉默认的csrf认证
        http.authorizeRequests()
            .antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and()
            .logout().permitAll()
            .and()
            .formLogin();
        http.csrf().disable();
    }
}

现在启动项目,继续访问http://localhost:8080/会发现可以成功访问了,而访问http://localhost:8080/test则会被拦截。因为我们在SpringSecurityConfig类中配置了放行主路径/的请求和注销请求,而拦截所有其他请求。【这里省略演示过程】

好了,我们继续完善配置。Controller类中新增一个接口test2:

//ROLE_是SpringS ecurity要求的权限前缀,参考源码:private String defaultRolePrefix = "ROLE_";
//这里@PreAuthorize注解发生在方法执行前,意思是要求执行此方法要有ADMIN权限
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/test2")
public String test2(){
    return "admin auth";
}

回到SpringSecurityConfig类中,新增重写父类的configure方法:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //注意:使用springsecurity5,需要加上{noop}指定使用NoOpPasswordEncoder给DelegatingPasswordEncoder去校验密码
    //,同时需要知道NoOpPasswordEncoder已经过时了,这里仅是为了方便
    auth.inMemoryAuthentication().withUser("admin").password("{noop}admin").roles("ADMIN");
    auth.inMemoryAuthentication().withUser("scott").password("{noop}scott").roles("USER");
}

重新启动项目,现在访问http://localhost:8080/test输入账号/密码为admin/admin就可以通过验证,而其它的如scott用户则不可以。
【这里省略演示过程】

到这里,我们的Spring Security配置还没有结束,我们继续进行最后一步。
创建一个MyPasswordEncoder并实现PasswordEncoder接口,具体实现如下:

public class MyPasswordEncoder implements PasswordEncoder {
    @Override
    public String encode(CharSequence charSequence){
        BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
        return bCryptEncoder.encode(charSequence);
    }
    @Override
    public boolean matches(CharSequence charSequence,String s) {
        BCryptPasswordEncoder bCryptEncoder = new BCryptPasswordEncoder();
        return bCryptEncoder.matches(charSequence, s);
    }
}

这个是密码校验类,我们这里采用了bCrypt加密算法(PS:原本打算用MD5的,可是发现似乎Spring Security5没有了这个MD5的Encode类,在StackOverflow搜索,由于个人搜索能力有限,也没弄明白,恳请知道的大佬解答下)。

现在,我们回到SpringSecurityConfig类中修改configure方法的实现:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //使用自己的密码校验类
    auth.userDetailsService(myUserService).passwordEncoder(new MyPasswordEncoder());
    //数据库管理方面支持的默认处理
    auth.jdbcAuthentication()
        .usersByUsernameQuery("")
        .authoritiesByUsernameQuery("")
        .passwordEncoder(new MyPasswordEncoder());
}

至此,Spring Security环境搭建完毕,当然一些注解如@PreAuthrize、@PostAuthrize、@PreFilter、@PostFilter等注解的使用方式比较复杂,无关本篇文章的主题,所以我就没有叙述,不过其简单使用已经注释在源代码中了。-> 获取源码

猜你喜欢

转载自blog.csdn.net/honhong1024/article/details/80056394