Spring Security介绍

Spring Security是Spring提供的一个安全框架,提供认证和授权功能,最主要的是它提供了简单的使用方式,同时又有很高的灵活性,简单,灵活,强大。

基础

SecurityContextHolder,SecurityContext,Authentication是Spring Security的基础对象。

  • SecurityContextHolder:存储当前的SecurityContext,即认证用户的上下文信息,内部使用ThreadLocal。
  • SecurityContext:持有Authentication对象和其他可能需要的信息
  • UserDetails:从Authentication中获取的对象,代表当前用户的具体信息
  • UserDetailsService:获取UserDetails的逻辑,一般封装了查询用户的逻辑,内部只有一个方法:
    • .UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
  • GrantedAuthority:当前用户获取到的授权信息。

在应用中获取当前用户信息:

Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (principal instanceof UserDetails) {
    String username = ((UserDetails)principal).getUsername();
} else {
    String username = principal.toString();
}

案例

1 Spring Boot项目中引入Spring Security的依赖包


        org.springframework.boot
        spring-boot-starter-security

2 配置SpringSecurity的安全信息

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // @formatter:off
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .antMatchers("/css/**", "/index").permitAll()
                    
                    // 只有USER权限的角色才能访问/user/接口
                    .antMatchers("/user/**").hasRole("USER")
                    .and()
                .formLogin().loginPage("/login").failureUrl("/login-error");
    }

//  @Autowired
//  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//      auth
//          .inMemoryAuthentication()
//              .withUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER"));
//  }
    // @formatter:on

    // 密码明文
    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
        return encoder;
    }


  // 获取用户的来源
    @Bean
    public UserDetailsService userDetailsService(){
        UserDetailsService userDetailsService = new UserDetailsService(){

            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
                if (StringUtils.isEmpty(username) || !"admin".equalsIgnoreCase(username)){
                    return null;
                }

                HashSet hashSet = new HashSet<>();
                // 内部检验权限,要以ROLE为前缀
                hashSet.add(new  SimpleGrantedAuthority("ROLE_USER") );
                User user = new User("admin","test",hashSet);

                return user;
            }
        };
        return userDetailsService;
    }
}

3 编写接口类

@Controller
public class MainController {

    @RequestMapping("/")
    public String root() {
        return "redirect:/index";
    }

    @ResponseBody
    @RequestMapping("/index")
    public String index() {
        return "当前为未经安全认证的页面";
    }

    @ResponseBody
    @RequestMapping("/user/index")
    public String userIndex() {
        SecurityContext securityContext = SecurityContextHolder.getContext();
        
        return "user/index";
    }

    @RequestMapping("/login")
    public String login() {
        return "login";
    }

    @ResponseBody
    @RequestMapping("/login-error")
    public String loginError(Model model) {
//      model.addAttribute("loginError", true);
        return "login-error";
    }

}

4 登录页面

// 位置 src/main/resources/templates/login.html



    
        Login page
        
        
    
    
        

Login page

Example user: user / password

Wrong user or password

:
:

Back to home page

5 效果。

  • 当直接访问/user/index页面的时候会因为安全配置重定向到login页面
  • 我们的UserService只配置了admin/test的用户,只有用admin用户才能登录成功
  • 登录成功之后再访问/user/index页面才生效

6 如果想要测试授权功能,在userDetailsService中返回结果去掉ROLE_USER权限即可。

调试关键点

org.springframework.security.access.vote.AffirmativeBased#decide 判断用户是否有权访问当前接口

org.springframework.security.authentication.dao.DaoAuthenticationProvider#additionalAuthenticationChecks 密码加密校验

最后

本文简单介绍了Spring Security的基础内容,给了一个简单的案例,自行运行查看效果

你可能感兴趣的:(Spring Security介绍)