SpringSecurity框架学习
导入security与thyemleaf与security整合的依赖
注意!SpringBoot版本过高可能不支持 最低支持2.0.9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity4 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
SpringSecurity配置文件
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.bcrypt.BCryptPasswordEncoder;
@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");
//没有权限回跳到登陆页面
//开启登陆页面
//定制登录页
http.formLogin ().loginPage ("/toLogin").usernameParameter ("user").passwordParameter ("pwd").loginProcessingUrl ("/login");
//开启注销功能 注销成功后返回首页
http.logout ().logoutSuccessUrl ("/");
//登出失败原因
http.csrf ().disable ();//关闭csrf功能 防止csrf攻击
//开启记住我功能 默认保存两周
http.rememberMe ().rememberMeParameter ("remember");
/*自定义接受前端参数*/
}
@Override //认证
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//可以从数据库读也可以从内存读
//密码编码加密
//在springSecurity 5.0+中新增了许多加密方式
auth.inMemoryAuthentication ().passwordEncoder (new BCryptPasswordEncoder ())
.withUser ("jsp").password (new BCryptPasswordEncoder ().encode ("123456")).roles ("vip2","vip3")
.and ()
.withUser ("root").password (new BCryptPasswordEncoder ().encode ("123456")).roles ("vip1","vip2","vip3")
.and ()
.withUser ("hcy").password (new BCryptPasswordEncoder ().encode ("123456")).roles ("vip1");
}
/* Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sat Dec 04 15:32:24 CST 2021
There was an unexpected error (type=Forbidden, status=403).*/
}
注意配置定制登录页时,需要注意前端传来的用户名密码是否与源码中默认相同,否则登录不会生效
前端代码如下
<form th:action="@{/login}" method="post"> **此处需要与 loginPage ("/toLogin")相同,如果不同需配置 loginProcessingUrl ("/login")**
<div class="field">
<label>Username</label>
<div class="ui left icon input">
<input type="text" placeholder="Username" name="user">
<i class="user icon"></i>
</div>
</div>
<div class="field">
<label>Password</label>
<div class="ui left icon input">
<input type="password" name="pwd">
<i class="lock icon"></i>
</div>
</form>
默认源码如下
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
* }
*
前端html页面联合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>
</a>
</div>
<!--根据用户角色动态实现-->
<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>
Controller层代码如下
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "/views/login";
}
}