网站成品下载,asp语言网站建设,wordpress模板 付费,静态网站有哪些SpringSecurity框架学习与使用 SpringSecurity学习SpringSecurity入门SpringSecurity深入认证授权自定义授权失败页面权限注解SecuredPreAuthorizePostAuthorizePostFilterPreFilter 参考 SpringSecurity学习
SpringSecurity入门
引入相关的依赖#xff0c;SpringBoot的版本… SpringSecurity框架学习与使用 SpringSecurity学习SpringSecurity入门SpringSecurity深入认证授权自定义授权失败页面权限注解SecuredPreAuthorizePostAuthorizePostFilterPreFilter 参考 SpringSecurity学习
SpringSecurity入门
引入相关的依赖SpringBoot的版本是2.7.10 dependencygroupIdorg.thymeleaf.extras/groupIdartifactIdthymeleaf-extras-springsecurity6/artifactIdversion3.1.1.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-thymeleaf/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency前端页面编写home.html、hello.html、login.html
hello.html
!DOCTYPE html
html xmlnshttp://www.w3.org/1999/xhtml xmlns:thhttps://www.thymeleaf.orgxmlns:sechttps://www.thymeleaf.org/thymeleaf-extras-springsecurity6
headtitleHello World!/title
/head
body
h1 th:inlinetextHello span th:removetag sec:authenticationnamethymeleaf/span!/h1
form th:action{/logout} methodpostinput typesubmit valueSign Out/
/form
/body
/htmlhome.html
!DOCTYPE html
html xmlnshttp://www.w3.org/1999/xhtml xmlns:thhttps://www.thymeleaf.org
headtitleSpring Security Example/title
/head
body
h1Welcome!/h1pClick a th:href{/templates/hello.html}here/a to see a greeting./p
/body
/htmllogin.html
!DOCTYPE html
html xmlnshttp://www.w3.org/1999/xhtml xmlns:thhttps://www.thymeleaf.org
headtitleSpring Security Example /title
/head
body
div th:if${param.error}Invalid username and password.
/div
div th:if${param.logout}You have been logged out.
/div
form th:action{/login} methodpostdivlabel User Name : input typetext nameusername/ /label/divdivlabel Password: input typepassword namepassword/ /label/divdivinput typesubmit valueSign In//div
/form
/body
/html视图控制访问对应的url跳转到不同的页面
/*** 视图配置*/
Configuration
public class MvcConfig implements WebMvcConfigurer {Overridepublic void addViewControllers(ViewControllerRegistry registry) {WebMvcConfigurer.super.addViewControllers(registry);//请求/home时显示home.html页面registry.addViewController(/home).setViewName(home);registry.addViewController(/).setViewName(home);registry.addViewController(/hello).setViewName(hello);registry.addViewController(/login).setViewName(login);}
}SpringSecurity配置
Configuration
EnableWebSecurity
public class WebSecurityConfig {Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request - {request.antMatchers(/).permitAll()// /home、/ 的请求可以访问.antMatchers(/home).permitAll() //除了上面的请求其它的请求必须认证通过.anyRequest().authenticated(); })//设置登录页面以及允许访问登录页面,springSecurity是有自带的默认登录页面的如果不 设置会跳转到默认的登录页面.formLogin((form) - form.loginPage(/login).permitAll()) //允许访问登出页面.logout(LogoutConfigurer::permitAll);return http.build();}/*** 设置默认的登录密码这里是直接使用存放在内存中的密码* 实际开发从数据库中查询读取* return*/Beanpublic UserDetailsService userDetailsService() {UserDetails user User.withDefaultPasswordEncoder().username(user).password(password).roles(USER).build();return new InMemoryUserDetailsManager(user);}
}结果 登录失败时 登录成功
SpringSecurity深入
认证
上面的demo中我们是把登录密码放在内存中记录着的除了这种方式外我们还可以在配置文件中设置登录用户名和密码 实际开发中一般都从数据库中进行读取因此我们需要实现UserDetailsService接口这个接口中有一个loadUserByUsername方法我们在这个方法中根据username查询用户的信息如果查询到了就把用户的信息封装成UserDetails返回。
用户输入的密码会被我们注入的PasswordEncoder加密所以在后面模拟的从数据库中查询用户密码的时候对输入的密码使用PasswordEncoder加密了。 /*** 密码加密* return*/Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}用户认证接口实现
Service(userDetailService)
public class MyUserDetailServiceImpl implements UserDetailsService {Autowiredprivate PasswordEncoder passwordEncoder;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//模拟从数据库中查询出密码if (zhangsan.equals(username)) {username zhangsan;String password passwordEncoder.encode(root);return new User(username, password, true, true, true, true,AuthorityUtils.commaSeparatedStringToAuthorityList(admin, ROLE_SALES));}throw new UsernameNotFoundException(用户没有找到);}}授权
前面我们对用户认证进行了讲解接下来讲如何授权。 在SpringSecurity中用户认证和授权的过程是很紧密的在loadUserByUsername方法返回的UserDetails的构造函数中最后一个参数就是用户具有的权限。而在Shiro中授权和认证是分为两个方法的。
在SpringSecurity中我们通过AuthorizedUrl类的方法来确定访问指定的url需要的请求和角色。
方法作用hasAuthority如果当前的主体具有指定的权限则返回 true,否则返回 falsehasAnyAuthority如果当前的主体有任何提供的角色给定的作为一个逗号分隔的字符串列表的话返回truehasRole如果用户具备给定角色就允许访问,否则出现 403。如果当前主体具有指定的角色则返回 truehasAnyRole表示用户具备任何一个条件都可以访问 url/test/test1只有SALES角色才能访问 url/test/test2只有admin权限才能访问 Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request - {request.antMatchers(/).permitAll().antMatchers(/home).permitAll() // /home、/ 的请求可以访问//需要SALES角色才可以访问.antMatchers(/test/test1).hasRole(SALES)//需要admin权限才能访问.antMatchers(/test/test2).hasAuthority(admin).anyRequest().authenticated(); //除了上面的其它的请求必须认证通过}).formLogin((form) - form.loginPage(/login).permitAll()) //设置登录页面以及允许访问登录页面.logout(LogoutConfigurer::permitAll);return http.build();}自定义授权失败页面 Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request - {request.antMatchers(/).permitAll().antMatchers(/home).permitAll() // /home、/ 的请求可以访问.antMatchers(/test/test1).hasRole(SALES).antMatchers(/test/test2).hasAuthority(admin).anyRequest().authenticated(); //除了上面的其它的请求必须认证通过});//设置没有权限访问跳转自定义页面http.exceptionHandling().accessDeniedPage(/error.html);http.formLogin((form) - {//设置登录页面以及允许访问登录页面form.loginPage(/login).permitAll()//登录访问路径.loginProcessingUrl(/login)//登录成功之后的跳转路径.defaultSuccessUrl(/hello).permitAll(); }).logout(LogoutConfigurer::permitAll);return http.build();}
权限注解
注解作用Secured判断是否具有角色另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_PreAuthorize注解适合进入方法前的权限验证 PreAuthorize 可以将登录用户的 roles/permissions 参数传到方法中PostAuthorize在方法执行后再进行权限验证适合验证带有返回值的权限PostFilter权限验证之后对数据进行过滤 留下用户名是 admin1 的数据
Secured
Secured判断是否具有角色另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“ 使用Secured注解之前需要先使用注解EnableGlobalMethodSecurity(securedEnabledtrue)开启此功能
RequestMapping(testSecured)
ResponseBody
Secured({ROLE_normal,ROLE_admin}) //判断是否有normal、admin角色
public String helloUser() {
return hello,user;
}PreAuthorize
PreAuthorize注解适合进入方法前的权限验证 PreAuthorize 可以将登录用户的 roles/permissions 参数传到方法中同样的使用之前也需要使用EnableGlobalMethodSecurity(prePostEnabled true)开启此功能
RequestMapping(/preAuthorize)
ResponseBody
PreAuthorize(hasAnyAuthority(menu:system))
public String preAuthorize(){System.out.println(preAuthorize);
return preAuthorize;
}PostAuthorize
PostAuthorize在方法执行后再进行权限验证适合验证带有返回值的权限
RequestMapping(/testPostAuthorize)
ResponseBody
PostAuthorize(hasAnyAuthority(menu:system))
public String preAuthorize(){
System.out.println(test--PostAuthorize);
return PostAuthorize;
}PostFilter
PostFilter 权限验证之后对数据进行过滤 留下用户名是 admin1 的数据 表达式中的 filterObject 引用的是方法返回值 List 中的某一个元素
RequestMapping(getAll)
PreAuthorize(hasRole(ROLE_管理员))
PostFilter(filterObject.username admin1)
ResponseBody
public ListUserInfo getAllUser(){ArrayListUserInfo list new ArrayList();list.add(new UserInfo(1l,admin1,6666));list.add(new UserInfo(2l,admin2,888));
return list;
}PreFilter
PreFilter: 进入控制器之前对数据进行过滤
RequestMapping(getTestPreFilter)
PreAuthorize(hasRole(ROLE_管理员))
PreFilter(value filterObject.id%20)
ResponseBody
public ListUserInfo getTestPreFilter(RequestBody ListUserInfo
list){list.forEach(t- {System.out.println(t.getId()\tt.getUsername());});
return list;
}除了上面提到的注解外还有权限表达式权限表达式
参考
SpringSecurity视频SpringSecurity教程SpringSecurity文档