前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Security 在 Spring Boot 中的使用【集中式】

Spring Security 在 Spring Boot 中的使用【集中式】

作者头像
Demo_Null
发布2020-10-28 14:58:58
2.5K0
发布2020-10-28 14:58:58
举报
文章被收录于专栏:Java 学习

1.1 准备

1.1.1 创建 Spring Boot 项目

  创建好一个空的 Spring Boot 项目之后,写一个 controller 验证此时是可以直接访问到该控制器的。

1.1.2 引入 Spring Security

  在 Spring Boot 中引入 Spring Security 是相当简单的,可以在用脚手架创建项目的时候勾选,也可以创建完毕后在 pom 文件中加入相关依赖。

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

  引入 Spring Security 后再次访问会发现直接被弹到了登录页面,此时我们还什么都没有配置,为什么 Security 会生效呢,这是因为 Spring Boot 帮我们完成了在 Spring 中需要完成的诸多配置【☞ Spring Security 基础入门】。也正是因为 Spring Boot 提供了自动化配置方案,让我们可以“零配置”的使用 Spring Security,所以在 Spring Boot 项目中我们通常使用的安全框架是 Spring Security 而在 Spring 中一般使用 Shiro。

  我们并没有配置静态的用户那么该如何登录呢,Spring Boot 为我们提供了一个默认的用户,用户名为:user,密码则是在启动 Spring Boot 项目是随机生成的,我们可以在控制台找到他。

1.2 配置认证

1.2.1 添加静态用户

  Spring Boot 除了一些信息写道 yml 配置文件中,其他配置都使用配置类,Spring Security 需要继承 WebSecurityConfigurerAdapter,配置用户信息需要重写 configure(AuthenticationManagerBuilder auth) 方法。配置完毕后,将不会再使用 user 用户。

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/18
 * @description Spring Security 配置类
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置静态用户
        auth.inMemoryAuthentication()
                .withUser("admin")
                .password("{noop}123")      // 此处需要加 {noop} 表示该密码为明文
                .roles("USER");
    }
}

1.2.2 添加数据库认证

☞ 添加用户实体类

  Spring Security 中使用的用户是 UserDetails,我们要么让自定义用户类实现 UserDetails,要么使用时将自定义用户类转换为 UserDetails。建议实现 UserDetails。因为该类中涉及到角色信息所以我们还需要创建角色类。我们在以后的操作中可能会将对象转为 json 或者将 json 转为对象,所以我们重写的方法需要加上 @JsonIgnore 将其忽略(该类本来就需要的不用忽略)。

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author gaohu9712@163.com
 * @date 2020/10/18
 * @description 用户实体类
 */
public class SysUser implements UserDetails {

    private Long id;
    private String username;
    private String passwrod;
    private List<SysRole> roleList = new ArrayList<>();


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public void setUsername(String username) {
        this.username = username;
    }


    public void setPasswrod(String passwrod) {
        this.passwrod = passwrod;
    }

    public List<SysRole> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<SysRole> roleList) {
        this.roleList = roleList;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return roleList;
    }

    @Override
    public String getPassword() {
        return passwrod;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    @JsonIgnore
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    @JsonIgnore
    public boolean isEnabled() {
        return false;
    }
}
☞ 创建角色类

  Spring Security 中使用的角色信息使用的是 GrantedAuthority 所以我们的角色类也需要实现 GrantedAuthority。

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/18
 * @description 角色类
 */
public class SysRole implements GrantedAuthority {

    private Long id;
    private String roleName;
    private String roleDesc;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }

    @Override
    @JsonIgnore
    public String getAuthority() {
        return roleName;
    }
}
☞ 添加持久层

此处省略使用通用 mapper 操作数据库的内容【☞ Mybatis 使用通用 mapper】,jpa 等其他操作数据库的方法亦可。

☞ 认证类

  Spring Boot 中 Spring Security 的认证类与 Spring 中的并无区别,都需要实现 UserDetailsService 接口,然后重写 loadUserByUsername(String s) 方法并返回一个 UserDetails。

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/18
 * @description 认证类
 */ 
public class UserDetailsServiceImpl implements UserDetailsService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        return userMapper.findByName(s);
    }
}
☞ 配置类
代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/18
 * @description Spring Security 配置类
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    // BCrypt 交由 Ioc 容器管理
    public BCryptPasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 认证类
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
}

1.3 授权

1.3.1 开启方法级授权

  在启动类上使用 @EnableGlobalMethodSecurity 注解开启方法级授权。参数 prePostEnabled 代表 Spring 中的权限控制注解;securedEnabled 代表 Spring Security 中的权限控制注解; jsr250Enabled 代表 jsr250 的权限控制注解

代码语言:javascript
复制
@SpringBootApplication
@MapperScan("com.software.springsecurity.mapper")
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringSecurityApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringSecurityApplication.class, args);
    }

}

1.3.2 添加方法权限

  当用户仅有 ROLE_USER 权限时仅能访问 findStr 方法而不能访问 get 方法;要想访问 get 方法用户必须具有 ROLE_ADMIN 权限。

代码语言:javascript
复制
/**
 * Created with IntelliJ IDEA.
 *
 * @author Demo_Null
 * @date 2020/10/18
 * @description
 */
@RestController
@RequestMapping("/demo")
public class DemoController {

    @GetMapping("/find")
    @Secured("ROLE_USER")
    public String findStr() {
        return "请求成功";
    }

    @GetMapping("/get")
    @Secured("ROLE_ADMIN")
    public String get() {
        return "get";
    }
}

1.3.3 异常拦截页面

代码语言:javascript
复制
@ControllerAdvice
public class HandlerControllerAdvice {

    @ExceptionHandler(AccessDeniedException.class)
    public String handlerException(){
        return "redirect:/403.html";
    }

    @ExceptionHandler(RuntimeException.class)
    public String runtimeHandlerException(){
        return "redirect:/500.html";
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 准备
    • 1.1.1 创建 Spring Boot 项目
      • 1.1.2 引入 Spring Security
      • 1.2 配置认证
        • 1.2.1 添加静态用户
          • 1.2.2 添加数据库认证
            • ☞ 添加用户实体类
            • ☞ 创建角色类
            • ☞ 添加持久层
            • ☞ 认证类
            • ☞ 配置类
        • 1.3 授权
          • 1.3.1 开启方法级授权
            • 1.3.2 添加方法权限
              • 1.3.3 异常拦截页面
              相关产品与服务
              数据库
              云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档