学习笔记——在Springboot中使用spring security(二):在内存中配置用户

一、前言

上一篇博客记录了仅仅加入spring security依赖,Springboot做的一些自动化配置。这些自动化配置已经可以完成一个完整的登录流程。但是系统不可能只有这一个用户,密码也不能每次启动程序都会改变。所以这篇博客记录一下,在内存中配置用户,以及自定义一些其他的操作。

二、开整

2.1、在配置文件中添加自定义用户

在内存中配置用户的最简单方法就是在配置文件中添加用户

spring:
  security:
    user:
      name: wtq
      password: 123456

添加完配置后,再次启动程序会发现控制台不再打印自动生成的密码了,这时候再次访问后端的接口或资源,就可以使用自定义的账户或密码。
在这里插入图片描述

2.2、在配置类中添加用户

Springboot中可以在配置文件中配置的组件,在配置类中都可以完成。只需要创建一个配置类SecurityConfig,继承WebSecurityConfigurerAdapter类,重写里面的configure(AuthenticationManagerBuilder auth)方法。这里还为这个角色配置了一个角色roles,这里先不展开。
如果想要配置多个用户,可以用and()将每个角色的信息隔开。

/**
 * @author wangtianqi
 * @create 2020-11-06 10:01
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // 提供密码加密方法的bean,这里先不加密
    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 在内存中配置用户
        auth.inMemoryAuthentication()
                .withUser("wtq")
                .password("123")
                .roles("admin")
                .and()
                .withUser("lyy")
                .password("123")
                .roles("user");
    }
}

使用第二个用户尝试登陆系统
在这里插入图片描述
登陆成功了
在这里插入图片描述

2.3、自定义登录表单

如果你感觉Springboot默认的登录表单不太好看,可以配置自己的登录表单。
首先准备一个好看的登录表单。
在这里插入图片描述

然后在刚刚的配置类中重写configure(HttpSecurity http)方法,所有的方法我都添加了注释。
其中.defaultSuccessUrl("/index.html")这个方法,要单独说一下。

在 Spring Security 中,和登录成功重定向 URL 相关的方法有两个:

  • defaultSuccessUrl
  • successForwardUrl

这两个咋看没什么区别,实际上内藏乾坤。

首先我们在配置的时候,defaultSuccessUrlsuccessForwardUrl 只需要配置一个即可,具体配置哪个,则要看你的需求,两个的区别如下:

  • defaultSuccessUrl 有一个重载的方法,我们先说一个参数的 defaultSuccessUrl 方法。如果我们在 defaultSuccessUrl 中指定登录成功的跳转页面为 /index,此时分两种情况,如果你是直接在浏览器中输入的登录地址,登录成功后,就直接跳转到 /index,如果你是在浏览器中输入了其他地址,例如 http://localhost:8080/hello,结果因为没有登录,又重定向到登录页面,此时登录成功后,就不会来到 /index ,而是来到 /hello 页面。

  • defaultSuccessUrl 还有一个重载的方法,第二个参数如果不设置默认为 false,也就是我们上面的的情况,如果手动设置第二个参数为 true,则 defaultSuccessUrl 的效果和 successForwardUrl 一致。

  • successForwardUrl 表示不管你是从哪里来的,登录后一律跳转到 successForwardUrl 指定的地址。例如 successForwardUrl 指定的地址为 /index ,你在浏览器地址栏输入 http://localhost:8080/hello,结果因为没有登录,重定向到登录页面,当你登录成功之后,就会服务端跳转到 /index 页面;或者你直接就在浏览器输入了登录页面地址,登录成功后也是来到 /index。

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                // 配置登录表单
                .formLogin()
                // 配置登录页
                .loginPage("/login.html")
                // 配置登录接口Url,默认也是:/doLogin。可以自己定义
                .loginProcessingUrl("/doLogin")
                // 配置username参数名称(默认为:username)
                .usernameParameter("user")
                // 配置password参数名称(默认为:password)
                .passwordParameter("pass")
                .defaultSuccessUrl("/index.html")
                // 放行登录相关的页面/接口
                .permitAll()
                .and()
                .csrf().disable();

登录页面中的表单部分

<form action="/doLogin" method="post">
            <div class="input">
                <label for="name">用户名</label>
                <input type="text" name="user" id="name">
                <span class="spin"></span>
            </div>
            <div class="input">
                <label for="pass">密码</label>
                <input type="password" name="pass" id="pass">
                <span class="spin"></span>
            </div>
            <div class="button login">
                <button type="submit">
                    <span>登录</span>
                    <i class="fa fa-check"></i>
                </button>
            </div>
        </form>

这时候再次访问登录页面,发现页面样式没有了。因为之前说过,如果不加以配置,spring security会默认保护所有的资源,包括静态资源。所以我们猜测,样式文件被spring security保护起来了。如果是这样,在我们登录完成之后,登录页面的样式就会恢复正常。
在这里插入图片描述
登陆一下,果然,像我们猜测的一样,静态资源被拦截了。
在这里插入图片描述
这时候只需要在刚刚的配置文件中,重写configure(WebSecurity web)方法。

@Override
    public void configure(WebSecurity web) throws Exception {
        // 放行这些路径下的静态资源
        web.ignoring().antMatchers("/js/**", "/css/**","/images/**");
    }

再次访问登录页面。发现样式也恢复正常了。

2.4、多安全规则配置

如果你的系统中需要多个拦截规则。直接举例说明。下面这两个方法,AdminSecurityConfig规定了/admin/**路径下的所有请求都需要已登录的用户拥有admin角色才可以访问。OtherSecurityConfig可以做一些其他的规定。

/**
 * @author wangtianqi
 * @create 2020-11-07 8:42
 */
@Configuration
//@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class MultiHttpSecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 在内存中配置用户
        auth.inMemoryAuthentication()
                .withUser("wtq")
                .password("123")
                .roles("admin")
                .and()
                .withUser("lyy")
                .password("123")
                .roles("user")
        ;
    }

    @Configuration
    @Order(1)
    // 配置多个安全规则
    public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/admin/**")
                    .authorizeRequests()
                    .anyRequest()
                    .hasRole("admin");
        }
    }

    @Configuration
    public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginProcessingUrl("/doLogin")
                    .permitAll()
                    .and()
                    .csrf().disable();
        }
    }
}

准备一个简单的接口

    @GetMapping("/admin/hello")
    public String helloAdmin() {
        return "Hello admin!";
    }

测试一下,使用admin账户访问一下,成功访问到了
在这里插入图片描述

在使用user账户访问一下这个页面,失败了,被拦截了。
在这里插入图片描述

2.5、权限配置

除了这种路径上的拦截外,还有粒度更小的权限配置。例如对方法的访问权限。实现方法的访问权限也十分简单。
只需要在2.4的代码基础上添加这样一个注解,第一个参数prePostEnabled表示开启基于方法的安全认证机制,第二个参数securedEnabled表示开启使用注解限制方法调用。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class MultiHttpSecurityConfig {

准备测试接口

hello()方法两个角色都可以访问
helloAdmin()仅admin用户可以访问
helloUser()仅user用户可以访问

/**
 * @author wangtianqi
 * @create 2020-09-17 13:36
 */
@RestController
@RequestMapping("/Hello")
public class HelloSpringBoot {

    @GetMapping("/SpringBoot")
    @PreAuthorize("hasAnyRole('admin','user')")
    public String hello() {
        return "Hello SpringBoot!";
    }

    @GetMapping("/admin")
    @PreAuthorize("hasRole('admin')")
    public String helloAdmin() {
        return "Hello admin!";
    }

    @PreAuthorize("hasRole('user')")
    @GetMapping("/user")
    public String helloUser() {
        return "Hello user!";
    }

测试一下,首先访问一下hello方法,成功
在这里插入图片描述
访问admin方法,成功
在这里插入图片描述
访问user方法,失败,并且抛出了AccessDeniedException异常。在这里插入图片描述
user用户就不测试啦。

在内存中配置用户,并且了解一些基础的配置。但是在正常的系统中,用户信息肯定是保存在数据库中的,这些就留在下一篇博客里吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值