①、解决默认进入login页面的方法
当我们在创建springboot的时候选择了springsecurity maven就会发现一直跳转在springsecurity自带的login页面
1、直接将maven去除
2、加上(exclude = {SecurityAutoConfiguration.class})
//取消登录验证
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
3、可以设置login的账号和密码
spring.security.user.name=admin
spring.security.user.password=admin
spring.security.user.roles=vip1
4、可以实现WebSecurityConfigurerAdapter这个类,重写里面的方法
@EnableWebSecurity // Enable 使xxx生效
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
②、主要功能授权和认证(访问控制)
记住这几个类:
-
WebSecurityConfigurerAdapter:自定义Security策略
-
AuthenticationManagerBuilder:自定义认证策略
-
@EnableWebSecurity:开启WebSecurity模式
1、引入springsecurity依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、编写配置类 继承WebSecurityConfigurerAdapter
一定要加上@EnableWebSecurity使之生效
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
3、请求的授权规则
authorizeRequests 授权请求 (authentication 认证)
这是链式编程
现在我们只是设置了vip1、vip2、vip3分别可以访问对应的视图,但这个时候除了首页能进,其他都进不了
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
//此时除了首页全进不去了,因为我们目前没有登录的角色,
//因为请求需要登录的角色拥有相应的权限才可以!
.antMatchers("/").permitAll()//首页所有人都可以访问
.antMatchers("/level1/**").hasRole("vip1") //如果是vip1可以访问level1下面的所有内容
.antMatchers("/level2/**").hasRole("vip2") //如果是vip2可以访问level2下面的所有内容
.antMatchers("/level3/**").hasRole("vip3"); //如果是vip3可以访问level3下面的所有内容
}
}
4、开启配置的登录功能
这是跳转到springsecurity自带的login页面
http.formLogin(); //作用:跳到登录页
5、设置用户权限
- 设置root拥有所有权限
- lcslcs只拥有vip1权限
- 兰兰拥有vip2、vip3权限
//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//在内存中定义,也可以在jdbc中去拿....
auth.inMemoryAuthentication()
.withUser("root").password("123456").roles("vip1","vip2","vip3")
.and()
.withUser("lcslcs").password("lcslcs").roles("vip1")
.and()
.withUser("lanlan").password("lanlan").roles("vip2","vip3");
}
6、密码加密
There is no PasswordEncoder mapped for the id “null”
springsecurity自带的加密规则 不加密明文进不去
//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("lcslcs").password(new BCryptPasswordEncoder().encode("lcslcs")).roles("vip1")
.and()
.withUser("lanlan").password(new BCryptPasswordEncoder().encode("lanlan")).roles("vip2","vip3");
}
7、测试成功,完整代码
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//定义认证规则
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("lcslcs").password(new BCryptPasswordEncoder().encode("lcslcs")).roles("vip1")
.and()
.withUser("lanlan").password(new BCryptPasswordEncoder().encode("lanlan")).roles("vip2","vip3");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 定制首页所有人可以访问
http.authorizeRequests()
//此时除了首页全进不去了,因为我们目前没有登录的角色,
//因为请求需要登录的角色拥有相应的权限才可以!
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//开启自动装配的登录功能
//login 请求来到登录页
//login?error重定向到这里表示登录失败
http.formLogin();
//测试发现,原本除了首页都进不去 现在直接跳转到登录页面
}
}
③、注销
1、直接在configure下面添加一个http.logout()
并让他返回首页
//注销 之后 跳回首页
http.logout().logoutSuccessUrl("/");
2、前端加上注销按钮
<!--@{/logout} 是springSecurity提供的-->
<a class="item" th:href="@{/logout}">
<i class="address card icon"></i>注销
</a>
④、只显示权限内的内容
根据个人权限显示相应的内容,切合实际应用
结合thymeleaf中的一些功能
sec:authorize="isAuthenticated()":是否认证登录!来显示不同的页面
1、Maven依赖
<!-- 其实就是thymeleaf 结合 springsecutity的一个包 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
2、导入命名空间
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
3、设置显示
如果未登录只显示登录
登录之后不显示登录只显示注销
<!--登录注销-->
<div class="right menu">
<!--如果未登录-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/login}">
<i class="address card icon"></i> 登录
</a>
</div>
<!--如果已登录-->
<div sec:authorize="isAuthenticated()">
<a class="item">
<i class="address card icon"></i>
用户名:<span sec:authentication="principal.username"></span>
角色:<span sec:authentication="principal.authorities"></span>
</a>
</div>
<div sec:authorize="isAuthenticated()">
<a class="item" th:href="@{/logout}">
<i class="address card icon"></i> 注销
</a>
</div>
</div>
4、角色功能显示
给标签设置权限
sec:authorize="hasRole('vip3')"
<!-- sec:authorize="hasRole('vip1')" -->
<div class="column" sec:authorize="hasRole('vip1')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 1</h5>
<hr>
<div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>
<div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>
<div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip2')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 2</h5>
<hr>
<div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>
<div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>
<div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>
</div>
</div>
</div>
</div>
<div class="column" sec:authorize="hasRole('vip3')">
<div class="ui raised segment">
<div class="ui">
<div class="content">
<h5 class="content">Level 3</h5>
<hr>
<div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>
<div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>
<div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>
</div>
</div>
</div>
</div>
⑤、记住我
类似于注销
1、开启记住我功能
//记住我
http.rememberMe();
2、前台application中可以看到保存在cookie里面的时间默认为两周
3、点击注销,默认删除remember me
4、结论
登录成功后,将cookie发送给浏览器进行保存,以后登录都带上这个cookie,只要通过检查就可以免登录了。但点击注销就会删除这个cookie。
⑥、定制登录页
现在我们的登录页都是springsecurity自带的,我们需要将登录页设置成我们自己的
1、在登录页面指定我们自己的登录页
直接在后面拼接(链式)
http.formlogin().loginPage("/toLogin");
2、前端登录按钮指向我们自定义的登录请求
<!--如果未登录-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
</div>
3、提交方式必需为post
@RequestMapping("/toLogin")
public String toLogin(){
return "view/login";
}
4、跳转我们的login视图
<form th:action="@{/login}" method="post">
账号:<input type="text" name="name"><br>
密码:<input type="password" name="password"><br>
<input type="checkbox" name="remember">记住我
<input type="submit">
</form>
5、请求提交
设置form表单中的name、password,springsecurity默认的是username、password
如果我们不用默认的必需后端进行指定
http.formLogin()
.usernameParameter("name")//对应我们表单里面的name
.passwordParameter("password")//对应我们表单里面的password
.loginPage("/toLogin")//对应我们首页的登录
.loginProcessingUrl("/login");//登录表单请求
5、记住我
<input type="checkbox" name="remember">记住我
6、记住我的后端验证处理
//定制记住我的参数!
http.rememberMe().rememberMeParameter("remember");