目录
简介
注意:
准备工作
pom.xml
RouterController
特别讲解:
一、授权
SecurityConfig---1.1
SecurityConfig---1.2
源码 formLogin
二、身份验证
核心类:Authentication 身份验证
SecurityConfig---2.1
SecurityConfig---2.2
JDBC
源码 auth.inMemoryAuthentication()
三、注销 http.logout();
源码 http.logout();
实例:
四、防止网站被攻击
五、权限登录---根据不同的用户显示不同的版块
Security—thymeleaf整合
1.导入命名空间
2. 上面隐藏
3.下面隐藏
六、记住我功能
七、定制自己的登录页面
问题一:前后端页面请求url 不一致
方式一: 修改前后端修改一致
方式二: loginProcessingUrl
问题二: 前后端传递参数不一致
SecurityConfig
RouterController
Spring Security是针对Spring项目的安全框架,也是SpringBoot底层安全模块默认的技术选型,他可以实现强大的Web安全控制,对于安全控制,我们仅需要引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理!
记住几个类:
Spring Security的两个主要目标是“认证”和“授权”(访问控制)。
"认证”(Authentication)
"授权"(Authorization)
这个概念是通用的,而不是只在Spring Security中存在。参考官网:
SpringBoot支持Security 版本不超过 2.0.9
官网:Spring Security Reference
org.springframework.boot
spring-boot-starter-thymeleaf
@Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String toIndex(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
@RequestMapping("/level1/{id}")
public String toLevel1(@PathVariable("id")Integer id){
return "views/level1/"+id;
}
@RequestMapping("/level2/{id}")
public String toLevel2(@PathVariable("id")Integer id){
return "views/level2/"+id;
}
@RequestMapping("/level3/{id}")
public String toLevel3(@PathVariable("id")Integer id){
return "views/level3/"+id;
}
}
@RequestMapping("/level1/{id}")
public String toLevel1(@PathVariable("id")Integer id){
return "views/level1/"+id;
}
//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权 链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
//请求授权的规则
http.authorizeRequests().antMatchers("/","/index").permitAll() //首页所有人可以访问
.antMatchers("/level1/**").hasRole("vip1") //level1 下得所有页面 需要拥有 hasRole vip1 才可以访问
.antMatchers("/level2/**").hasRole("vip2") //level2 下得所有页面 需要拥有 hasRole vip2 才可以访问
.antMatchers("/level3/**").hasRole("vip3"); //level3 下得所有页面 需要拥有 hasRole vip3 才可以访问
}
}
//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权 链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
//请求授权的规则
http.authorizeRequests().antMatchers("/","/index").permitAll() //首页所有人可以访问
.antMatchers("/level1/**").hasRole("vip1") //level1 下得所有页面 需要拥有 hasRole vip1 才可以访问
.antMatchers("/level2/**").hasRole("vip2") //level2 下得所有页面 需要拥有 hasRole vip2 才可以访问
.antMatchers("/level3/**").hasRole("vip3"); //level3 下得所有页面 需要拥有 hasRole vip3 才可以访问
//没有权限 默认跳到登录页面
http.formLogin();
}
}
源码 formLogin
/**
* Specifies to support form based authentication. If
* {@link FormLoginConfigurer#loginPage(String)} is not specified a default login page
* will be generated.
*
* Example Configurations
*
* The most basic configuration defaults to automatically generating a login page at
* the URL "/login", redirecting to "/login?error" for authentication failure. The
* details of the login page can be found on
* {@link FormLoginConfigurer#loginPage(String)}
*
*
* @Configuration
* @EnableWebSecurity
* public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter {
*
* @Override
* protected void configure(HttpSecurity http) throws Exception {
* http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin();
* }
*
* @Override
* protected void configure(AuthenticationManagerBuilder auth) throws Exception {
* auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
* }
* }
*
*
* The configuration below demonstrates customizing the defaults.
*
*
* @Configuration
* @EnableWebSecurity
* public class FormLoginSecurityConfig extends WebSecurityConfigurerAdapter {
*
* @Override
* protected void configure(HttpSecurity http) throws Exception {
* http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin()
* .usernameParameter("username") // default is username
* .passwordParameter("password") // default is password
* .loginPage("/authentication/login") // default is /login with an HTTP get
* .failureUrl("/authentication/login?failed") // default is /login?error
* .loginProcessingUrl("/authentication/login/process"); // default is /login
* // with an HTTP
* // post
* }
*
* @Override
* protected void configure(AuthenticationManagerBuilder auth) throws Exception {
* auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
* }
* }
*
*
* @see FormLoginConfigurer#loginPage(String)
*
* @return the {@link FormLoginConfigurer} for further customizations
* @throws Exception
*/
public FormLoginConfigurer formLogin() throws Exception {
return getOrApply(new FormLoginConfigurer<>());
}
注:
//认证 springboot 2.1.X 可以直接使用 //密码编码 PasswordEncoder //在spring Security 5.0+ 新增了很多的加密方法~
底部
//认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库中读取 jdbcAuthentication() 此时是 内存中读取inMemoryAuthentication
auth.inMemoryAuthentication()
.withUser("kuangshen").password("123456").roles("vip2","vip3")
.and()
.withUser("root").password("123456").roles("vip1","vip2","vip3")
.and()
.withUser("guest").password("123456").roles("vip1","vip3")
}
//认证 springboot 2.1.X 可以直接使用
//密码编码 PasswordEncoder
//在spring Security 5.0+ 新增了很多的加密方法~
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库中读取 jdbcAuthentication() 此时是 内存中读取inMemoryAuthentication
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //密码加密的方式
.withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") //编码
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
源码 auth.inMemoryAuthentication()
//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权 链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
//请求授权的规则
http.authorizeRequests().antMatchers("/","/index").permitAll() //首页所有人可以访问
.antMatchers("/level1/**").hasRole("vip1") //level1 下得所有页面 需要拥有 hasRole vip1 才可以访问
.antMatchers("/level2/**").hasRole("vip2") //level2 下得所有页面 需要拥有 hasRole vip2 才可以访问
.antMatchers("/level3/**").hasRole("vip3"); //level3 下得所有页面 需要拥有 hasRole vip3 才可以访问
//没有权限 默认跳到登录页面
http.formLogin();
//注销,开启了注销功能
http.logout();
}
}
http.logout().deleteCookies("remove").invalidateHttpSession(true);//移除所有的Cookie 清空所有的Session //注销 登出成功后跳转到 首页 http.logout().logoutSuccessUrl("/");
源码 http.logout();
/**
* Provides logout support. This is automatically applied when using
* {@link WebSecurityConfigurerAdapter}. The default is that accessing the URL
* "/logout" will log the user out by invalidating the HTTP Session, cleaning up any
* {@link #rememberMe()} authentication that was configured, clearing the
* {@link SecurityContextHolder}, and then redirect to "/login?success".
*
* Example Custom Configuration
*
* The following customization to log out when the URL "/custom-logout" is invoked.
* Log out will remove the cookie named "remove", not invalidate the HttpSession,
* clear the SecurityContextHolder, and upon completion redirect to "/logout-success".
*
*
* @Configuration
* @EnableWebSecurity
* public class LogoutSecurityConfig extends WebSecurityConfigurerAdapter {
*
* @Override
* protected void configure(HttpSecurity http) throws Exception {
* http.authorizeRequests().antMatchers("/**").hasRole("USER").and().formLogin()
* .and()
* // sample logout customization
* .logout().deleteCookies("remove").invalidateHttpSession(false)
* .logoutUrl("/custom-logout").logoutSuccessUrl("/logout-success");
* }
*
* @Override
* protected void configure(AuthenticationManagerBuilder auth) throws Exception {
* auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
* }
* }
*
*
* @return the {@link LogoutConfigurer} for further customizations
* @throws Exception
*/
//防止网站攻击工具 get post http.csrf().disable(); //关闭csrf 功能 登出失败 可能存在的原因
org.thymeleaf.extras
thymeleaf-extras-springsecurity4
3.0.4.RELEASE
作用: 在 thymeleaf 中可以写一些 Security 的操作
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
//记住我功能 cookie 默认保存两周 //rememberMeParameter 记住我的参数 http.rememberMe().rememberMeParameter("remember");
//定制自己的登录页面 http.formLogin().loginPage("/toLogin");
http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");
//前后端 传递的参数不一致 默认 username password
http.formLogin().loginPage("/toLogin")
.usernameParameter("user")
.passwordParameter("pwd").loginProcessingUrl("/login");
/**
* Security配置文件
*/
//AOP : 拦截器!
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权 链式编程
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有对应有权限的人才能访问
//请求授权的规则
http.authorizeRequests().antMatchers("/","/index").permitAll() //首页所有人可以访问
.antMatchers("/level1/**").hasRole("vip1") //level1 下得所有页面 需要拥有 hasRole vip1 才可以访问
.antMatchers("/level2/**").hasRole("vip2") //level2 下得所有页面 需要拥有 hasRole vip2 才可以访问
.antMatchers("/level3/**").hasRole("vip3"); //level3 下得所有页面 需要拥有 hasRole vip3 才可以访问
//没有权限 默认跳到登录页面
http.formLogin();
//定制自己的登录页面
// 方式一:
// http.formLogin().loginPage("/toLogin"); 网页请求写 toLogin
// 问题一: loginProcessingUrl 登录认证的是那个url 网页写 login
http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");
// 问题二: 前后端 传递的参数不一致 默认 username password
// http.formLogin().loginPage("/toLogin")
// .usernameParameter("user")
// .passwordParameter("pwd").loginProcessingUrl("/login");
//注销 登出成功后跳转到index.html
http.logout();
//注销 登出成功后跳转到 首页
http.logout().logoutSuccessUrl("/");
//防止网站攻击工具 get post
http.csrf().disable(); //关闭csrf 功能 登出失败 可能存在的原因
//记住我功能 cookie 默认保存两周
//rememberMeParameter 记住我的参数
http.rememberMe().rememberMeParameter("remember");
// //定制首页可以随意访问 另一种方式
// http.authorizeRequests().antMatchers("/","/index").permitAll();
//
// //level1页面:vip1 2 3 都可以访问该页面
// http.authorizeRequests().antMatchers("/level1/**").hasRole("vip1");
//
// //level2页面:vip2 3可以访问
// http.authorizeRequests().antMatchers("/level2/**").hasRole("vip2");
//
// //level3页面:vip3才能访问
// http.authorizeRequests().antMatchers("/level3/**").hasRole("vip3");
}
//认证 springboot 2.1.X 可以直接使用
//密码编码 PasswordEncoder
//在spring Security 5.0+ 新增了很多的加密方法~
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该从数据库中读取 jdbcAuthentication() 此时是 内存中读取inMemoryAuthentication
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //密码加密的方式
.withUser("kuangshen").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3") //编码
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1");
}
}
@Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String toIndex(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "views/login";
}
@RequestMapping("/level1/{id}")
public String toLevel1(@PathVariable("id")Integer id){
return "views/level1/"+id;
}
@RequestMapping("/level2/{id}")
public String toLevel2(@PathVariable("id")Integer id){
return "views/level2/"+id;
}
@RequestMapping("/level3/{id}")
public String toLevel3(@PathVariable("id")Integer id){
return "views/level3/"+id;
}
}