1、认识SpringSecurity
Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入 spring-boot-starter-security 模块,进行少量的配置,即可实现强大的安全管理。
记住几个类:
-
WebSecurityConfigurerAdapter:自定义Security策略
-
AuthenticationManagerBuilder:自定义认证策略
-
@EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
“认证”(Authentication)
身份验证是关于验证您的凭据,如用户名/用户ID和密码,以验证您的身份。
身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
“授权” (Authorization)
授权发生在系统成功验证您的身份后,最终会授予您访问资源(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
这个概念是通用的,而不是只在Spring Security 中存在。
2、认证和授权的配置
SpringSecurity.class
/** * @author lj on 2020/9/10. * @version 1.0 */ @EnableWebSecurity public class SpringSecurity extends WebSecurityConfigurerAdapter { @Autowired UserServiceImpl userService; //请求授权验证 @Override protected void configure(HttpSecurity http) throws Exception { // .denyAll(); //拒绝访问 // .authenticated(); //需认证通过 // .permitAll(); //无条件允许访问 // 访问权限 http.authorizeRequests() .antMatchers("/","/index").permitAll() .antMatchers("/register","/login","/toLogin").permitAll() .antMatchers("/*").authenticated() .antMatchers("/level1/**").hasRole("vip1") .antMatchers("/level2/**").hasRole("管理员") .antMatchers("/level3/**").hasRole("管理员"); // 登录配置 http.formLogin() .usernameParameter("username") .passwordParameter("password") .loginPage("/toLogin") //自己的登入页 .loginProcessingUrl("/login") // 登陆表单提交请求 .defaultSuccessUrl("/index"); // 设置默认登录成功后跳转的页面 // 注销配置 http.headers().contentTypeOptions().disable(); http.headers().frameOptions().disable(); // 图片跨域 http.csrf().disable();//关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求 http.logout().logoutSuccessUrl("/"); // 记住我配置 http.rememberMe().rememberMeParameter("remember"); } // 用户授权验证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); } // 密码加密方式 @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
UserServiceImpl.class是userService接口的实现类,而它又去实现了UserDetailsService,所以可以用来用户认证的
// 用户授权验证 @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService).passwordEncoder(passwordEncoder()); }
UserServiceImpl.class全部代码:
/** * <p> * 服务实现类 * </p> * * @author liujun * @since 2020-09-10 */ @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService, UserDetailsService { @Autowired UserService userService; @Autowired RoleService roleService; @Autowired HttpSession session; @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {// 通过用户名查询用户 // User user = userService.getOne(new QueryWrapper<User>().eq("name", s)); final List<User> users = userService.list(new QueryWrapper<User>().eq("name", s)); final User user = users.get(0); // 放入session session.setAttribute("loginUser", user); //创建一个新的UserDetails对象,最后验证登陆的需要 UserDetails userDetails = null; if (user != null) { //System.out.println("未加密:"+user.getPassword()); String BCryptPassword = new BCryptPasswordEncoder().encode(user.getPwd()); // 登录后会将登录密码进行加密,然后比对数据库中的密码,数据库密码需要加密存储!(这里很恶心!) String password = user.getPwd(); //创建一个集合来存放权限 Collection<GrantedAuthority> authorities = getAuthorities(user); //实例化UserDetails对象 userDetails = new org.springframework.security.core.userdetails.User(s, BCryptPassword, true, true, true, true, authorities); } return userDetails; } private Collection<GrantedAuthority> getAuthorities (User user){ final List<Role> roles = roleService.list(new QueryWrapper<Role>().eq("user_id", user.getId())); List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>(); roles.forEach(role -> authList.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()))); return authList; } }
以上只展示部分代码,全部源码请参考:https://gitee.com/liujun1681/spring-security/