整合thymeleaf+spring-security
学习记录
thymeleaf+spring-security
<!--在pom.xml中添加依赖-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
<!--在html中的<html>添加后,出现代码提示,解决"报红"-->
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
动态登陆状态
<!--未登录,显示登录按钮-->
<div sec:authorize="!isAuthenticated()">
<a class="item" th:href="@{/toLogin}">
<i class="address card icon"></i> 登录
</a>
</div>
<!--登陆后,显示用户名,注销-->
<div sec:authorize="isAuthenticated()">
<a class="item">
用户名: <span sec:authentication="name"></span>
角色: <span sec:authentication="authorities"></span>
</a>
<a class="item" th:href="@{/logout}">
<i class="sign-out icon"></i> 注销
</a>
</div>
跟据权限动态显示:
<div class="column" sec:authorize="hasRole('vip1')"> 11 </div>
<!--权限为vip1,可见-->
我的SecurityConfig
:
/**
* @author Sept Zhang
* @create 2020-09-07 20:01
*/
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//链式编程
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,功能页只有拥有权限的人才能访问
//授权的规则
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限默认转到登陆页面,需要开启登录页面
//定制登录页 loginPage("/toLogin")
//登陆认证页面 loginProcessingUrl(),登陆th:action="@{/login}"的值
http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login");
//防止网站攻击 get
http.csrf().disable();//关闭CSRF功能,不关闭 logoutUrl("/") 会404
//注销
http.logout().logoutSuccessUrl("/");
//开启账号登陆记录,通过cookie实现,默认保存两周,可手动清除
//rememberMeParameter("remeberMe")自定义
http.rememberMe().rememberMeParameter("remeberMe");
}
//认证,spring 2.1.x
//报错:密码编码 There is no PasswordEncoder mapped for the id "null"
//在Spring Security 5.0+ 新增了很多加密方法
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
.and()
.withUser("admin").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
.and()
.withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip3");
}
}
报错:
AuthenticationManagerBuilder.inMemoryAuthentication().password("123456")
//报错:密码编码 There is no PasswordEncoder mapped for the id "null"
//原因:明文密码,可以通过反编译,破解密码,Spring Security 不允许
//解决: new BCryptPasswordEncoder().encode("123456")
//解决:使用BCryptPasswordEncoder加密
我的 UserController
/**
* @author Sept Zhang
* @create 2020-09-07 19:05
*/
@Controller
public class UserController {
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
@RequestMapping({"/toLogin"})
public String toLogin(){
return "views/login";
}
@RequestMapping({"/level1/{id}"})
public String level1(@PathVariable("id") int id){
return "views/level1/"+id;
}
}
登陆页面(login.html
)
<form th:action="@{/login}" method="post">
<div class="field">
<label>Username</label>
<div class="ui left icon input">
<input type="text" placeholder="Username" name="username">
<i class="user icon"></i>
</div>
</div>
<div class="field">
<label>Password</label>
<div class="ui left icon input">
<input type="password" name="password">
<i class="lock icon"></i>
</div>
</div>
<div class="field">
<label>Password</label>
<div class="ui left icon input">
<input type="checkbox" name="remeberMe"> 记住我
</div>
</div>
<input type="submit" class="ui blue submit button"/>
</form>
相关源码(HttpSecurity.java
)的注释:
HttpSecurity.class;
/**
*
* 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)}
*
* @Override
* protected void configure(HttpSecurity http) throws Exception {
* [
](https://www.bilibili.com/video/BV1PE411i7CV?p=1) 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
* }
*
*/
学习参考:
遇见狂神说