前提备注

  • 进阶到这个之前,需要先了解最基本SpringBoot搭建及RestAPI的实现,略。
  • 如果没有搭建好,建议回头先搭建基础环境。

代码逻辑

  • pom.xml引入

    1. <dependency>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-security</artifactId>
    4. </dependency>
  • 然后运行(需要有自己Controller),然后访问Controller时,会提示需要登陆,用户名为user,密码为IDEA日志中的密码。

image.png

如何禁用

  • 在启动类中@SpringBootApplication后面加上一段exclusion即可。
  1. @SpringBootApplication(exclude=SecurityAutoConfiguration.class)

自定义用户名和密码

  • 方案一:配置文件application.properties中加上以下代码

    1. spring.security.user.name=admin
    2. spring.security.user.password=123456
  • 方案二:基于内存的认证(及多用户)

  • 注意最新版本不能将密码明文存储在内存中,而需要做一次密码加密。
  • 如果不做加密的话,报错信息如下:

    1. There is no PasswordEncoder mapped for the id "null"
  • 正确写法:使用@Bean注解引入

    1. @Configuration
    2. @EnableWebSecurity
    3. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    4. @Override
    5. protected void configure(AuthenticationManagerBuilder auth) throws Exception{
    6. auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles();
    7. auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("123456")).roles();
    8. }
    9. @Bean
    10. public PasswordEncoder passwordEncoder() {
    11. return new BCryptPasswordEncoder();
    12. }
    13. }
  • 正确写法二:使用private引入加密(不如写法一简洁) ```java

public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() //认证信息存储到内存中 .passwordEncoder(passwordEncoder()) .withUser(“user”).password(passwordEncoder().encode(“123456”)).roles(); } private PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

  1. - **基于内存的角色授权**
  2. - 需求缘起:实际项目中两个账号会有不同角色,比如管理员和普通用户,对于不同角色,允许的方法也不一样。
  3. ```java
  4. auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("123456")).roles("admin","user");
  • 开启方法级的安全控制
    • 在@Configuration注解的类上,再添加@EnableGlobalMethodSecurity注解。
  1. @Configuration
  2. @EnableWebSecurity
  3. @EnableGlobalMethodSecurity(prePostEnabled = true)
  • 配置方法级别权限控制

    • 使用注解@PreAuthorize(“hasAnyRole(‘admin’)”)

      1. @RequestMapping(value="/hellouser")
      2. @PreAuthorize("hasAnyRole('admin','user')")
      3. public String hellouser(){
      4. return "Helloworld!";
      5. }
      6. @RequestMapping(value="/helloadmin")
      7. @PreAuthorize("hasAnyRole('admin')")
      8. public String helloadmin(){
      9. return "Helloworld!";
      10. }
  • 实际测试

    • 登陆user之后,访问hellouser时可以正常返回结果。
    • 但是访问helloadmin时会报错403没有权限。

拓展

  • 基于内存数据库的身份认证和角色授权 …
  • 基于Mysql的身份认证和角色授权 …
  • 自定义登陆页面和构建主页 …
  • 登出和403处理 …
  • 动态加载角色 …