SpringSecurity学习一 快速开始

simple

简单的SpringSecurity部署,仅从内存里配置用户数据。
项目源码gitte地址: https://gitee.com/xiang_Gitee/spring-security-learn(子工程simple)

推荐博文:
手把手带你入门 Spring Security!
Spring Security 入门原理及实战
干货|一个案例学会Spring Security 中使用 JWT

必要依赖

	<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>

实际上添加好依赖之后,配置好application.yml和启动类,不做其他配置SpringSecurity就已经生效,会在后台控制台上打印密码(用户名默认为user)
SpringSecurity学习一 快速开始
访问http://localhost:端口号 的任何url都会跳转到框架默认自带的登录页面
SpringSecurity学习一 快速开始
当然这是远不能满足我们需求的,需要进一步配置

简单配置

首先添加一个用以演示的控制器:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "登录成功";
    }

    @GetMapping("/home")
    public String home() {
        return "首页成功,未登录噢";
    }

    @GetMapping("/signin")
    public String login() {
        return "请先登录";
    }

    @GetMapping("/error")
    public String error() {
        return "登录失败";
    }
}

security配置类:
SecurityConfig 继承WebSecurityConfigurerAdapter 进行配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //认证需求路径
        http.authorizeRequests()
                .antMatchers("/", "/home")//添加ant风格的url匹配
                .permitAll()//上面两个url全部允许(放行)
                .anyRequest()//任何请求url
                .authenticated();//都需要验证

        //登录配置
        http.formLogin()
                .failureUrl("/error")//登录错误跳转
                .defaultSuccessUrl("/hello")//登录成功跳转
                .permitAll();//全部放行

        //登出配置
        http.logout()
                .logoutSuccessUrl("/home")//登出成功跳转
                .logoutUrl("/logout");//登出url
    }
    
    /**
     * 生成一个内存用户
     * @return
     */
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
                User.withDefaultPasswordEncoder()//处于演示可用,生产环境由于不安全而不建议使用
                        .username("user")
                        .password("password")
                        .build();
        return new InMemoryUserDetailsManager(user);
    }
}

在这个配置类中,做了两件事:
1. 覆盖configure(HttpSecurity http) 方法,规定了哪些url可以直接访问,其余需要验证之后访问,规定了登录的跳转页面。
2. 覆盖UserDetailsService userDetailsService()方法并注册为Bean,在里面手动生成了一个UserDetails,用户名为"user"密码为“password”,.withDefaultPasswordEncoder()表示密码不加密,InMemoryUserDetailsManager表示存入内存。

UserDetails是SpringSecurity中用以存储账户信息的类,UserDetailsService是用以获取UserDetails的接口,后面就是继承这个接口实现从数据库获取用户信息。

现在访问http://localhost:8080/hello,配置中除了"/", "/home"的url访问都需要验证,所以会跳转到默认的登录接口/login,也就是默认的登录页面,输入正确用户名和密码点击Sign 登录成功,访问/hello
SpringSecurity学习一 快速开始

自定义登录url

现在修改SecurityConfig的configure(HttpSecurity http)方法:

    @Override
protected void configure(HttpSecurity http) throws Exception {
        //认证需求路径
        http.authorizeRequests()
                .antMatchers("/", "/home")//添加ant风格的url匹配
                .permitAll()//上面两个url全部允许(放行)
                .anyRequest()//任何请求url
                .authenticated();//都需要验证

        //登录路径
        http.formLogin()
                .loginPage("/signin")
                .loginProcessingUrl("/dosignin")
                .failureUrl("/error")//登录错误跳转
                .defaultSuccessUrl("/hello")//登录成功跳转
                .permitAll();//全部放行

        //登出路径
        http.logout()
                .logoutSuccessUrl("/home")//登出成功跳转
                .logoutUrl("/logout");//登出url
    }

在登录配置那里加了两行配置
.loginPage("/signin")
登录界面,任何未登录的请求都会跳转到这个url,若controller未配置对应url,会默认跳转到一开始的那个html登陆界面,而此处若未配置url,则会默认跳转至"/login"
.loginProcessingUrl("/dosignin")
登录接口,通过这个接口实现登录,此处若未配置url,则会将loginPage设置的url(post方法)作为登录路径。

SpringSecurity的登录处理并不是通过配置Controller来进行登录,而是通过Filter,具体方法在下篇文章记录

如此配置好后,登录跳转就会转到/signin
SpringSecurity学习一 快速开始
通过postman访问/dosignin
SpringSecurity学习一 快速开始
结果:总之就是失败了
SpringSecurity学习一 快速开始
在之前的自带登录html里可以看到登录请求时除了用户名和密码之外还有一个隐藏参数_csrf,这个参数的具体原因在这里:spring security CSRF防护
在请求的时候带上_csrf参数即可,这里选择直接关闭这个默认配置:
SpringSecurity学习一 快速开始
重新运行访问
SpringSecurity学习一 快速开始

最终配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 设置通过拦截器保护请求
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {


        http.csrf().disable();//禁用跨域保护策略csrf。csrf默认开启,这样就得在登录时加个_csrf参数,演示环境可以禁用

        //认证需求路径
        http.authorizeRequests()
                .antMatchers("/", "/home")//添加ant风格的url匹配
                .permitAll()//上面两个url全部允许(放行)
                .anyRequest()//任何请求url
                .authenticated();//都需要验证

        //登录路径
        http.formLogin()
                .loginPage("/signin")//登录界面,未登录会跳转到这个url,若controller未配置对应url,会默认跳转一个的html登陆界面
                .loginProcessingUrl("/dosignin")//登录接口,通过这个接口实现登录,若未设置,则会将loginPage的设置url作为默认登录接口
                .failureUrl("/error")//登录错误跳转
                .defaultSuccessUrl("/hello")//登录成功跳转
                .permitAll();//全部放行

        //登出路径
        http.logout()
                .logoutSuccessUrl("/home")//登出成功跳转
                .logoutUrl("/logout");//登出url
    }
    /**
     * 生成一个内存用户
     * @return
     */
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
                User.withDefaultPasswordEncoder()//处于演示可用,生产环境由于不安全而不建议使用
                        .username("user")
                        .password("password")
                        .roles("USER")
                        .build();

        return new InMemoryUserDetailsManager(user);
    }
}
上一篇:SpringSecurity


下一篇:Java工具包下载