SpringBoot集成SpringSecurity(入门级)

简介: 目录Springboot集成SpringSecurity Demo 快速上手-初步入门: 创建单用户单角色的安全控制多用户多角色的实现思路 每个身份都使用一个登录实体类...

目录

目录创建于2017-12-18


Springboot集成SpringSecurity

Demo

快速上手-初步入门:

创建单用户单角色的安全控制

  • 添加依赖
   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
      @Autowired
      private ReaderRepository readerRepository;
      @Override
      protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            .antMatchers("/").access("hasRole('READER')")//要求登陆者进入根目录必须具有 READER 的角色
            .antMatchers("/**").permitAll()//其他页面开放了权限
          .and()
          .formLogin()
            .loginPage("/login")//登录表单的路径
            .failureUrl("/login?error=true");
      }
      @Override
      protected void configure(
                  AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(new UserDetailsService() {//定义自定义的UserDetailService
            @Override
            public UserDetails loadUserByUsername(String username)
                throws UsernameNotFoundException {
              UserDetails userDetails = readerRepository.findOne(username);
              if (userDetails != null) {
                return userDetails;
              }
              throw new UsernameNotFoundException("User '" + username + "' not found.");
            }
          });
      }
    }

Repository类

   public interface ReaderRepository extends JpaRepository<Reader, String> {}
    //登录实体类
    @Entity
    public class Reader implements UserDetails {
      private static final long serialVersionUID = 1L;
      @Id
      private String username;
      private String fullname;
      private String password;
      //省略setget
      //授予READER权限
      @Override
      public Collection<? extends GrantedAuthority> getAuthorities() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_READER"));
      }
      //不过期
      @Override
      public boolean isAccountNonExpired() { return true;}
      //不加锁
      @Override
      public boolean isAccountNonLocked() {return true;}
      //不禁用
      @Override
      public boolean isCredentialsNonExpired() {return true;}
      //可用
      @Override
      public boolean isEnabled() { return true;}
    }

多用户多角色的实现思路

  • 使用多个实体类(实现了UserDetails接口),一个权限类,再一个多对多连接,就得到了多用户,多权限的控制
  • 在页面上加上角色的判断来控制数据显示,业务操作等功能

  • 根据书上案例代码,可以得出结论,用户表,角色表,用户角色关联表,用户表是可以多张的,角色公用一张即可,然后关联表也对应的多张,就能实现具体的业务需求

    • 例如:一个网上在线阅读书城,作家和读者以及编辑,网站后台管理员等角色的不同权限对应的页面甚至页面上细分的各个模块
  • Author Admin Reader 三个类
    继承了UserDetails接口的实体类的配置

    //配置多对多的关系,用户和角色(权限)之间的关系,是通用的改下属性名即可
    @ManyToMany(cascade = {CascadeType.REFRESH},fetch = FetchType.EAGER)
    private List<AllRoles> roles ;
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
        List<AllRoles> roles = this.getRoles();
        for(AllRoles role:roles){
            auths.add(new SimpleGrantedAuthority(role.getRole_name()));
        }
        return auths;
    }
    // 登录的用户名,如果属性不是叫username,就要重写,返回应该的用户名属性就是了
    @Override
    public String getUsername() { return this.reader_name;}
    @Override
    public boolean isAccountNonExpired() {return true;}
    @Override
    public boolean isAccountNonLocked() {return true;}
    @Override
    public boolean isCredentialsNonExpired() {return true;}
    @Override
    public boolean isEnabled() {return true;}
每个身份都使用一个登录实体类
  • 然后使用不同的dao层查询,显然的实体类登录查询的效率及其低且不易扩展
  • 设置好spirng.jpa.hibernate.ddl-auto=update
  • 第一次运行还会有没有实体对应的表这样的提示,说明了他正在根据多对多映射创建实体表,也体现了这个多种用户模式下需要实体等量的连接表
  • 所以这个是要查询多张表了
    • (除非UserDetailService接口的loadUserByUsername能收到表类别的参数)
    • 也可以考虑使用一个字符串,然后用特殊字符把类型放进去,然后正则取出来
    • 登录页面就需要自定义一个函数进行拼接(或者使用校验来拼接?)
另一种思路:
  • 使用一个登录用户表(序列id,用户名,密码,用户编码(对应多张表))
  • 角色表(序列id,用户编码,角色)
    这样的话扩展就只要加表,使用同一个主键生成策略就可以了

  • 思考:

    • 其实这个安全框架使用的是角色控制,而不是权限控制,目前的了解,达不到Oracle那样的权限加角色控制

实现细节

关于注解的几种使用方式

@Secured

  • 这是基于Spring特定的注解

@RolesAllowed

  • JSR-250的@RolesAllowed Java标准定义的注解,与上面的注解是差不多的
  • 但是都是有局限性,只能判断请求是否有权限,不能进行更多的自定义判断

SpringSecurity3.0 开始提供了 SpEL表达式

需要先配置这个配置类,后面的注解才会生效

    @Configuration
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{}
  • @PreAuthorize 方法调用前,基于表达式的计算结果来限制方法的访问
  • @PostAuthorize 允许方法调用,如果表达式是false 抛出安全异常
  • @PostFilter 允许方法调用,按照表达式来过滤方法的结果
  • @PreFilter 允许方法调用,必须进入方法前过滤输入值

  • 方法调用前验证权限,示例:

    • @PreAuthorize("hasRole('ROLE_ADMIN')") 只允许该权限的用户访问
    • 方法入参user,限定读者用户的text长度小于140,或者是作家用户无限制
    • @PreAuthorize("(hasRole('ROLE_READER') and #user.text.length()<=140 ) or hasRole('ROLE_AUTHOR')")
  • 方法调用之后验证权限,示例;
    • @PostAuthorize("returnObject.spitter.username == principal.username")
    • public Spittle getSpittleById(long id){}
    • 保护方法,只有当返回的对象就是当前登录的用户时,才返回,不然抛出安全异常
      以上是保护方法的调用,但是有时候保护的是数据的输入输出:
  • 过滤方法的输入输出
    • 事后对方法的返回值进行过滤
      • @PreAuthorize("hasAnyRole({'ROLE_ADMIN','ROLE_USER'})")
      • @PostFilter("hasRole('ROLE_ADMIN') || filterObject.user.username == principal.name")
      • public List<User> getUsers(){}
      • 该示例就是限制了如果是管理员可以获取到所有数据,普通用户只能看到自己
      • 但是这种实现是不好的,只是一个例子,只获取自己,重载方法加个id参数就好了,上面的实现,把数据全拿出来再判断,性能上。。。
    • 事先对方法的参数进行过滤
      • @PreAuthorize("hasAnyRole({'ROLE_ADMIN','ROLE_USER'})")
      • @PreFilter("hasRole('ROLE_ADMIN') || targetObject.user.username == principal.name")
      • public void deleteUsers(){List<User> users}
      • 示例实现了传入一个集合,要删除的用户,但是当前用户只能删除自己,管理员才能删除集合里所有的用户
    • 定义许可计算器
      • @PreFilter("hasPermission(targetObject,'delete')") 用户是否有权限删除目标对象?
      • 使用了自定义的计算器类来实现这个判断,表达式简洁,但是自定义类不好写
      • 实现PermissionEvaluator接口,新建hasPermission方法,功能就是判断是否有权限,其实就是对比目标对象是不是当前用户
      • 创建好类后,重载GlobalMethodSecurityConfiguration配置类的createExpressionHalder方法,注册进去
      • DefaultMethodSecurityExperssionHandler ex = new De...();
      • ex.setPermissionEvaluator(new 自定义类);
      • return ex;

保护方法应用

  • @Secured 注解限制方法调用
目录
相关文章
|
1天前
|
消息中间件 存储 Java
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装
本教程介绍ActiveMQ的安装与基本使用。首先从官网下载apache-activemq-5.15.3版本,解压后即可完成安装,非常便捷。启动时进入解压目录下的bin文件夹,根据系统选择win32或win64,运行activemq.bat启动服务。通过浏览器访问`http://127.0.0.1:8161/admin/`可进入管理界面,默认用户名密码为admin/admin。ActiveMQ支持两种消息模式:点对点(Queue)和发布/订阅(Topic)。前者确保每条消息仅被一个消费者消费,后者允许多个消费者同时接收相同消息。
12 0
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ安装
|
1天前
|
NoSQL Java 关系型数据库
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
本文介绍在 Spring Boot 中集成 Redis 的方法。Redis 是一种支持多种数据结构的非关系型数据库(NoSQL),具备高并发、高性能和灵活扩展的特点,适用于缓存、实时数据分析等场景。其数据以键值对形式存储,支持字符串、哈希、列表、集合等类型。通过将 Redis 与 Mysql 集群结合使用,可实现数据同步,提升系统稳定性。例如,在网站架构中优先从 Redis 获取数据,故障时回退至 Mysql,确保服务不中断。
14 0
微服务——SpringBoot使用归纳——Spring Boot 中集成Redis——Redis 介绍
|
1天前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 的使用
本文介绍了 Thymeleaf 在 Spring Boot 项目中的使用方法,包括访问静态页面、处理对象和 List 数据、常用标签操作等内容。通过示例代码展示了如何配置 404 和 500 错误页面,以及如何在模板中渲染对象属性和列表数据。同时总结了常用的 Thymeleaf 标签,如 `th:value`、`th:if`、`th:each` 等,并提供了官方文档链接以供进一步学习。
15 0
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 的使用
|
1天前
|
JSON Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的使用
本文详细介绍了Swagger2的使用方法,包括在Spring Boot项目中的配置与应用。重点讲解了Swagger2中常用的注解,如实体类上的`@ApiModel`和`@ApiModelProperty`,Controller类上的`@Api`、`@ApiOperation`以及参数上的`@ApiParam`等。通过示例代码展示了如何为实体类和接口添加注解,并在页面上生成在线接口文档,实现接口测试。最后总结了Swagger的优势及其在项目开发中的重要性,提供了课程源代码下载链接供学习参考。
11 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的使用
|
1天前
|
缓存 Java API
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
本文介绍了在Spring Boot中配置Swagger2的方法。通过创建一个配置类,添加`@Configuration`和`@EnableSwagger2`注解,使用Docket对象定义API文档的详细信息,包括标题、描述、版本和包路径等。配置完成后,访问`localhost:8080/swagger-ui.html`即可查看接口文档。文中还提示了可能因浏览器缓存导致的问题及解决方法。
15 0
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的配置
|
1天前
|
安全 Java Apache
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 身份和权限认证
本文介绍了 Apache Shiro 的身份认证与权限认证机制。在身份认证部分,分析了 Shiro 的认证流程,包括应用程序调用 `Subject.login(token)` 方法、SecurityManager 接管认证以及通过 Realm 进行具体的安全验证。权限认证部分阐述了权限(permission)、角色(role)和用户(user)三者的关系,其中用户可拥有多个角色,角色则对应不同的权限组合,例如普通用户仅能查看或添加信息,而管理员可执行所有操作。
19 0
|
1天前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
16 0
|
1天前
|
消息中间件 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——发布/订阅消息的生产和消费
本文详细讲解了Spring Boot中ActiveMQ的发布/订阅消息机制,包括消息生产和消费的具体实现方式。生产端通过`sendMessage`方法发送订阅消息,消费端则需配置`application.yml`或自定义工厂以支持topic消息监听。为解决点对点与发布/订阅消息兼容问题,可通过设置`containerFactory`实现两者共存。最后,文章还提供了测试方法及总结,帮助读者掌握ActiveMQ在异步消息处理中的应用。
16 0
|
1天前
|
消息中间件 网络协议 Java
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ——ActiveMQ集成
本文介绍了在 Spring Boot 中集成 ActiveMQ 的详细步骤。首先通过引入 `spring-boot-starter-activemq` 依赖并配置 `application.yml` 文件实现基本设置。接着,创建 Queue 和 Topic 消息类型,分别使用 `ActiveMQQueue` 和 `ActiveMQTopic` 类完成配置。随后,利用 `JmsMessagingTemplate` 实现消息发送功能,并通过 Controller 和监听器实现点对点消息的生产和消费。最后,通过浏览器访问测试接口验证消息传递的成功性。
12 0
|
1天前
|
消息中间件 Java API
微服务——SpringBoot使用归纳——Spring Boot中集成ActiveMQ—— JMS 和 ActiveMQ 介绍
本文介绍如何在Spring Boot中集成ActiveMQ,首先阐述了JMS(Java消息服务)的概念及其作为与具体平台无关的API在异步通信中的作用。接着说明了JMS的主要对象模型,如连接工厂、会话、生产者和消费者等,并指出JMS支持点对点和发布/订阅两种消息类型。随后重点讲解了ActiveMQ,作为Apache开源的消息总线,它完全支持JMS规范,适用于异步消息处理。最后,文章探讨了在Spring Boot中使用队列(Queue)和主题(Topic)这两种消息通信形式的方法。
14 0

热门文章

最新文章