欢迎访问欧博网址!

上饶旅游网:在SpringBoot中使用SpringSecurity

admin2个月前5

@

目录
  • 提出一个需求
  • 解决方案:
  • 使用SpringSecurity举行解决
    • SpringSecurity和SpringBoot连系
      • 1. 首先在pom.xml中引入依赖:
      • 2. 设置用户角色和接口的权限关系
      • 3. 设置用户名和密码
      • 4.举行测试
    • 总结:

本教程是基于SpringMVC而建立的,不适用于WebFlux。(若是你不知道这两者,可以忽略这句提醒)

提出一个需求

所有的手艺是为了解决现实问题而泛起的,以是我们并不空谈,也不去讲那么多的观点。在这样一个系统中,有三个接口,需要授权给三种权限的人使用,如下表:

接口地址 需要的权限形貌 可接见的权限组名称
visitor/main 不需要权限,也不用登录,谁都可以接见
admin/main 必须登录,只有管理员可以接见 ADMIN
user/main 必须登录,管理员和用户权限都能接见 USER和ADMIN

解决方案:

  • 在Controller中判断用户是否登录和用户的权限组判断是否可以接见

    这是最不现实的解决方案,可是我刚进公司时的项目就是这样设计的,那时我还以为很高峻尚呢。

  • 使用Web应用的三大组件中和过滤器(Filter)举行判断

    这是正解,SpringSecurity也正是用的这个原理。若是你的项目足够简朴,建议你直接使用这种方式就可以了,并不需要集成SpringSecurity。这部门的示例在代码中有演示,自己下载代码查看即可。

  • 我们可以直接使用SpringSecurity框架来解决这个问题

使用SpringSecurity举行解决

​ 网上的教程那么多,然则讲的都不清不楚。以是,请仔细阅读下段这些话,这要比后边的代码主要。

​ SpringSecurity主要有两部门内容:

  • 认证 (你是谁,说白了就是一个用户登录的功效,帮我们验证用户名和密码)
  • 授权 (你醒目什么,就是凭据当前登录用户的权限,说明你能接见哪些接口,哪些不能接见。)

这里的登录是对于浏览器接见来说的,由于若是是前后端星散时,使用的是Token举行授权的,也可以明白为登录用户,这个后边会讲。这里只是为了知识的严谨性才提到了这点

SpringSecurity和SpringBoot连系

1. 首先在pom.xml中引入依赖:

<!-- 不用写版本,继续Springboot的版本-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>

2. 设置用户角色和接口的权限关系

是支持使用xml举行设置的,然则在SpringBoot中更建议使用Java注解设置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 设置用户权限组和接口路径的关系
     * 和一些其他设置
     *
     * @param http
     * @throws Exception
     */
    @Override
     protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()     // 对请求举行验证
                .antMatchers("/visitor/**").permitAll()
                .antMatchers("/admin/**").hasRole("ROLE_ADMIN")     // 必须有ADMIN权限
                .antMatchers("/user/**").hasAnyRole("ROLE_USER", "ROLE_ADMIN")       //有随便一种权限
                .anyRequest()     //随便请求(这里主要指方式)
                .authenticated()   //// 需要身份认证
                .and()   //示意一个设置的竣事
                .formLogin().permitAll()  //开启SpringSecurity内置的表单登录,会提供一个/login接口
                .and()
                .logout().permitAll()  //开启SpringSecurity内置的退出登录,会为我们提供一个/logout接口
                .and()
                .csrf().disable();    //关闭csrf跨站伪造请求
    }

}

上边的设置主要内容有两个:

  1. 设置接见三个接口(现实上不仅仅是3个,/**是泛指)需要的权限;
  2. 设置了使用SpringSecurity的内置/login和/loginout接口(这个是完全可以自定义的)
  3. 权限被拒绝后的返回效果也可以自定义,它当权限被拒绝后,会抛出异常

说明:

  1. 上边的设置中,实在就是挪用http的这个工具的方式;
  2. 使用.and()只为了示意一上设置竣事,并知足链式挪用的要求,否则之前的工具可能并不能举行链式挪用
  3. 这个设置在SpringBoot应用启动的时刻就会挪用,也就是会将这些设置加载进内存,当用户挪用对应的接口的时刻,就会判断它的角色是否可以挪用这个接口,流程图如下(我以为图要比文字更能说明历程):

3. 设置用户名和密码

​ 设置了上边的接口和用户权限角色的关系后,就是要设置我们的用户名和密码了。若是没有准确的用户名和密码,仙人也登录不上去。

​ 关于这个,网上的教程有林林总总的设置,实在就一个接口,我们只需要实现这个接口中的方式就可以了。接口代码如下:

package org.springframework.security.core.userdetails;

public interface UserDetailsService {
  	/**
  	 * 在登录的时刻,就会挪用这个方式,它的返回效果是一个UserDetails接口类
  	 */
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

​ 来看一下这个接口,若是想扩展,可以自己写一个实现类,也可以使用SpringSecurity提供的实现

public interface UserDetails extends Serializable {
  	// 用户授权聚集
    Collection<? extends GrantedAuthority> getAuthorities();
    String getPassword();
    String getUsername();
    boolean isAccountNonExpired();
    boolean isAccountNonLocked();
    boolean isCredentialsNonExpired();
    boolean isEnabled();
}

​ UserDetailsServicer接口的实现类

@Configuration
public class UserDetailsServiceImpl implements UserDetailsService {
    /**
     * 这个方式要返回一个UserDetails工具
     * 其中包罗用户名,密码,授权信息等
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        /**
         * 将我们的登录逻辑写在这里
         * 我是直接在这里写的死代码,实在应该从数据库中凭据用户名去查
         */
        if (username == null) {
            //返回null时,后边就会抛出异常,就会登录失败。但这个异常并不需要我们处置
            return null;
        }
        if (username.equals("lyn4ever")) {
            //这是组织用户权限组的代码
            //然则这个权限上加了ROLE_前缀,而在之前的设置上却没有加。
            //与其说这欠好明白,倒不如说这是他设计上的一个小缺陷
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
            List<SimpleGrantedAuthority> list = new ArrayList<>();
            list.add(authority);
            //这个user是UserDetails的一个实现类
            //用户密码现实是lyn4ever,前边加{noop}是不让SpringSecurity对密码举行加密,使用明文和输入的登录密码对照
            //若是不写{noop},它就会将表表单密码举行加密,然后和这个对比
            User user = new User("lyn4ever", "{noop}lyn4ever", list);
            return user;
        }
        if (username.equals("admin")) {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
            SimpleGrantedAuthority authority1 = new SimpleGrantedAuthority("ROLE_ADMIN");
            List<SimpleGrantedAuthority> list = new ArrayList<>();
            list.add(authority);
            list.add(authority1);
            User user = new User("admiin", "{noop}admin", list);
            return user;
        }

        //其他返回null
        return null;
    }
}

4.举行测试

​ 划分接见上边三个接口,可以看到接见效果和上边的流程是一样的。

总结:

  • 仔细阅读上边的谁人流程图,是明白SpringSecurity最主要的内容,代码啥的都很简朴;上边也就两个类,一个设置接口与角色的关系,一个实现了UserDetailsService类中的方式。
  • 前边说了,SpringSecurity主要就是两个逻辑:
    • 用户登录后,将用户的角色信息保存在服务器(session中);
    • 用户接见接口后,从session中取出用户信息,然后和设置的角色和权限举行比对是否有这个权限接见
  • 上述方式中,我们只重写了用户登录时的逻辑。而凭据接见接口来判断当前用户是否拥有这个接口的接见权限部门,我们并没有举行修改。以是这只适用于可以使用session的项目中。
  • 对于前后端星散的项目,一样平常是行使JWT举行授权的,以是它的主要内容就在判断token中的信息是否有接见这个接口的权限,而并不在用户登录这一部门。
  • 解决接见的方案有很多种,选择自己最适合自己的才是最好了。SpringSecurity只是提供了一系列的接口,他自己内部也有一些实现,你也可以直接使用。
  • 上边设置和用户登录逻辑部门的内容是完全可以从数据库中查询出来举行设置的。

代码地址

,

Sunbet

Sunbet www.cangzhoujinchang.com Sunbet简单方便,游戏种类繁多,现推出手机客户端app,在sunbet即可下载,随时随地体验游戏带来的精彩!

上一篇 下一篇

猜你喜欢

最新文章
热评文章
热门文章
随机文章
热门标签