SecurityConfig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | package com.jay.SpringBootStudy8.config; import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true , prePostEnabled = true ) //方法授权 public class SecurityConfig extends WebSecurityConfigurerAdapter { //用数据库查询的话,就不需要在这里模拟用户了 // @Bean // public UserDetailsService userDetailsService(){ // InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); // manager.createUser(User.withUsername("user2").password("123456").authorities("add","delete","update").roles("vip1").build()); // manager.createUser(User.withUsername("user3").password("123456").authorities("add","delete","update").roles("vip2").build()); // return manager; // } //密码编码器 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } //认证 // @Override // protected void configure(AuthenticationManagerBuilder auth) throws Exception { // super.configure(auth); //BCryptPasswordEncoder 加密方式,用户名admin、密码123456,可以and()连接多个 // auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) // .withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1") // .and() // .withUser("user1").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2") // ; // } //授权 @Override protected void configure(HttpSecurity http) throws Exception { //Security 创建 Session,使用Session保持会话,如果使用 jwt Token,则可以设置成STATELESS,不生成也不是用Session http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS); //使用方法授权,不需要下面的web授权配置 //功能页只有具有权限的人才能访问 // http.authorizeRequests() // .antMatchers("/level1").hasRole("vip1") // .antMatchers("/level2").hasRole("vip2") // .antMatchers("/level3").authenticated() // .anyRequest().permitAll(); //禁用csrf跨站 // <!--加上后不用禁用csrf--> // <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> // http.csrf().disable(); //开启登录,定制登录页,自定义请求参数名 和 登录请求地址。 //如果不自定义登录请求地址,那登录form的action需要是loginPage指定的地址 /userLogin http.formLogin().loginPage( "/userLogin" ) .usernameParameter( "name" ) .passwordParameter( "pwd" ) .loginProcessingUrl( "/userLogin" ) .successForwardUrl( "/level1" ) ; //记住我,自定义请求参数 http.rememberMe().rememberMeParameter( "remember" ); //注销、删除cookie、清除session、跳转登录页 http.logout().deleteCookies( "remove" ).invalidateHttpSession( true ).logoutSuccessUrl( "/userLogin" ); } } |
SpringDataUserDetailsService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | package com.jay.SpringBootStudy8.config; import com.jay.SpringBootStudy8.pojo.Permission; import com.jay.SpringBootStudy8.pojo.Role; import com.jay.SpringBootStudy8.pojo.SysUser; import com.jay.SpringBootStudy8.service.PermissionService; import com.jay.SpringBootStudy8.service.RoleService; import com.jay.SpringBootStudy8.service.SysUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @Service public class SpringDataUserDetailsService implements UserDetailsService { @Autowired private SysUserService sysUserService; @Autowired private RoleService roleService; @Autowired private PermissionService permissionService; //根据账户查询用户 @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { System. out .println( "userName:" + s); //连接数据库 123456 md5密码 efd9d1b8bfb00e8e3647990f7d74d1d8,BCrypt密码 $2a$10$bobysVYApzaZF2RhNcIQp.qum8V1e9jg5jkqStlRKkfXkB0y4P5AC SysUser user = sysUserService.getModelByUserName(s); if (user != null ) { List<Role> roles = roleService.getAllByUserId(user.getId()); List<String> roleNames = roles.stream().map(Role::getName).collect(Collectors.toList()); List<Integer> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList()); List<Permission> permissions = permissionService.getAllByRoleIds(roleIds); List<String> permissionCodes = permissions.stream().map(Permission::getCode).collect(Collectors.toList()); User.UserBuilder builder = User.withUsername(user.getUserName()).password(user.getPwd()); builder.authorities(permissionCodes.toArray( new String[0])); // builder.roles(roleNames.toArray(new String[0]));//roles会替换authorities的赋值 UserDetails userDetails = builder.build(); return userDetails; } return null ; } } |
Controller》Action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @RequestMapping( "/level1" ) @PreAuthorize( "hasAuthority('users:mgr')" ) //方法授权,方法执行前校验,建议使用 public String level1(Model model) { //得到当前认证通过的用户身份,用户的信息都在这里存着 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); //用户权限 Object credentials = authentication.getCredentials(); //用户凭证 Object details = authentication.getDetails(); //用户详细信息 Object principal = authentication.getPrincipal(); //用户身份 UserDetails userDetails = (UserDetails) principal; String userName = userDetails.getUsername(); model.addAttribute( "userName" ,userName); return "views/level1/1" ; } |
前端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!DOCTYPE html> <html lang= "en_US" xmlns:th= "http://www.thymeleaf.org" > <head> <meta charset= "UTF-8" /> <meta name= "viewport" content= "width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" > <meta http-equiv= "X-UA-Compatible" content= "ie=edge" > <title>login</title> </head> <body> <h1>login</h1> <a th:href= "@{/logout}" >注销</a> <a th:href= "@{/userLogin}" >login</a> <p th:text= "${msg}" style= "color: red;" ></p> <form method= "post" th:action= "@{/userLogin}" > <!--加上后不用禁用csrf--> <input type= "hidden" name= "${_csrf.parameterName}" value= "${_csrf.token}" /> name:<input type= "text" name= "name" /> <br/> pwd:<input type= "password" name= "pwd" /> <br/> <input type= "checkbox" name= "remember" />Remember Me <br/> <button type= "submit" >submit</button> </form> </body> </html> |
视频:https://www.bilibili.com/video/BV1VE411h7aL?p=25
分类:
Java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】