springboot security只会跳到login_Spring Boot学习12_安全

一、Demo(使用Thymeleaf整合Security)

  • pom.xml
 <properties>
    <!-- 切换Thymeleaf版本 -->
    <thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
    <!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
    <!-- thymeleaf2   layout1-->
    <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
 </properties>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
 </dependency>
​
 <!-- thymeleaf与security整合包 -->
 <dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
 </dependency>
  <!-- Thymeleaf -->
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>
  • Controller
@Controller
public class KungfuController {
 private final String PREFIX = "pages/";
 /**
  * 欢迎页
  * @return
  */
 @GetMapping("/")
 public String index() {
  return "welcome";
 }
 
 /**
  * 登陆页
  * @return
  */
 @GetMapping("/userlogin")
 public String loginPage() {
  return PREFIX+"login";
 }
 
 
 /**
  * level1页面映射
  * @param path
  * @return
  */
 @GetMapping("/level1/{path}")
 public String level1(@PathVariable("path")String path) {
  return PREFIX+"level1/"+path;
 }
 
 /**
  * level2页面映射
  * @param path
  * @return
  */
 @GetMapping("/level2/{path}")
 public String level2(@PathVariable("path")String path) {
  return PREFIX+"level2/"+path;
 }
 
 /**
  * level3页面映射
  * @param path
  * @return
  */
 @GetMapping("/level3/{path}")
 public String level3(@PathVariable("path")String path) {
  return PREFIX+"level3/"+path;
 }
}
  • WebSecurityConfigurerAdapter的子类MySecurityConfig,使用@EnableWebSecurity开启WEB安全
    1、定制请求的规则,/不需要经过授权,/level1/**需要VIP1的权限才能访问(没有权限就会跳到登录页面),其他同理
    2、默认开启了登录http.formLogin();,以Get方式请求/login就会跳转到Spring写好的登录页面,以Post请求/login就会处理登录请求(Spring会处理)
    3、自定义注销按钮http.logout();,设置请求/logout就会处理注销清除用户登录记录(Spring会处理),默认注销后重定向/login?logout(登录页面)请求中,通过http.logout().logoutSuccessUrl("/");自定义请求注销后重定向到哪个请求上
    4、开启记住我(自动登录)功能http.rememberMe();原理跟Servlet时期使用一样:把用户名和密码存到Cookie中,下次访问该网站时会带上Cookie,然后拦截到Cookie中的用户名和密码实现自动登录
    5、通过实现PasswordEncoder类在encode方法上直接返回原来的字符串,不需要编码。在matches方法中直接通过明文的方式匹配。
    6、定制认证规则(这里使用内存的方式),比如使用用户名zhangsan,密码12345登录就有VIP1VIP2的权限,其他同理,有了响应的权限之后就能访问对应的路径了
@EnableWebSecurity
public class MySecurityConfig 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();
 http.logout().logoutSuccessUrl("/");
 http.rememberMe();
    }
​
 /**
 * 定制认证规则
 * @param auth
 * @throws Exception
 */
 @Override
 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
 //可以设置内存指定的登录的账号密码,指定角色
 auth.inMemoryAuthentication()
 //这样,页面提交时候,密码以明文的方式进行匹配。
                .passwordEncoder(new MyPasswordEncoder())
                    .withUser("zhangsan").password("12345").roles("VIP1", "VIP2"                    , "VIP3")
                .and()
                    .withUser("lisi").password("12345").roles("VIP2", "VIP3")
                .and()
                   .withUser("wangwu").password("12345").roles("VIP1", "VIP3");
    }
​
 public class MyPasswordEncoder implements PasswordEncoder {
​
 @Override
 public String encode(CharSequence charSequence) {
    return charSequence.toString();
       }
 @Override
 public boolean matches(CharSequence charSequence, String s) {
     return s.equals(charSequence.toString());
       }
   }
}
  • 工程目录

v2-65c0d58ba3418c3e90a853d449a01b3f_b.jpg
  • 所有的秘籍展示

v2-bcbfc900630db2e8fa1056c4a9eaeb4a_b.jpg
  • 在html页面中使用Thymeleaf整合Security的标签
    welcome.html
    1、引入thymeleaf命名空间和thymeleaf整合security的标签xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"
    2、通过sec:authorize="!isAuthenticated()"标签判断是否授权来动态显示不同的内容
    3、通过sec:authentication="name"获取当前登录的用户名
    4、通过sec:authentication="principal.authorities"获取该用户所拥有的所有角色
    5、通过sec:authorize="hasRole('VIP1')"判断当前是否有VIP1角色的权限,其他同理,来达到每个用户拥有的不同的角色动态的显示自己能访问的内容
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
 xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<!-- 如果没有授权通过就显示游客 -->
<div sec:authorize="!isAuthenticated()">
 <h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
</div>
<!-- 如果授权通过了显示注销、用户信息、用户的角色 -->
<div sec:authorize="isAuthenticated()">
 <h2 align="center">
 <span sec:authentication="name"></span>
        您好,您的角色有
 <span sec:authentication="principal.authorities"></span>
 </h2>
 <form th:action="@{/logout}" method="post">
 <input type="submit" value="注销">
 </form>
</div>
<hr>
<div sec:authorize="hasRole('VIP1')">
 <h3>普通武功秘籍</h3>
 <ul>
 <li><a th:href="@{/level1/1}">罗汉拳</a></li>
 <li><a th:href="@{/level1/2}">武当长拳</a></li>
 <li><a th:href="@{/level1/3}">全真剑法</a></li>
 </ul>
</div>
<div sec:authorize="hasRole('VIP2')">
 <h3>高级武功秘籍</h3>
 <ul>
 <li><a th:href="@{/level2/1}">太极拳</a></li>
 <li><a th:href="@{/level2/2}">七伤拳</a></li>
 <li><a th:href="@{/level2/3}">梯云纵</a></li>
 </ul>
</div>
<div sec:authorize="hasRole('VIP3')">
 <h3>绝世武功秘籍</h3>
 <ul>
 <li><a th:href="@{/level3/1}">葵花宝典</a></li>
 <li><a th:href="@{/level3/2}">龟派气功</a></li>
 <li><a th:href="@{/level3/3}">独孤九剑</a></li>
 </ul>
</div>
</body>
</html>
  • 测试
    1、使用zhangsan用户登录

v2-86c0dd54e2ff2ded0f6b2016c88e359a_b.jpg


2、登录成功进入主页

v2-bf3e13b41ec8973829b25110ed0fecea_b.jpg


3、登录时勾选了记住我,所以Cookie中会带用户信息,退出浏览器之后再进入会自动登录

v2-42e9e3fdf6264a6c5e0d692313518694_b.jpg

二、自定义登录页面

1、前面说了默认请求登录页面和处理登录的方式,也可以通过下面这种方式来自定义登录页面http.formLogin().loginPage("/userlogin").usernameParameter("user").passwordParameter("pwd");

由默认就会变成Get请求/userlogin来到自己写好的登陆页面,或者请求没有权限的页面也会跳到/userlogin,Post请求/userlogin来处理登录(Spring会处理),参数名称默认为username,password,通过上面的方式可以自定义

2、登录页面的记住我可以通过http.rememberMe().rememberMeParameter("remeberme");自定义[记住我]功能的参数名(默认是remeber-me)

    @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("/userlogin")
                .usernameParameter("user").passwordParameter("pwd");
        http.logout().logoutSuccessUrl("/");
        http.rememberMe().rememberMeParameter("remeberme");
    }

3、登录页面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1 align="center">欢迎登陆武林秘籍管理系统</h1>
    <hr>
    <div align="center">
        <form th:action="@{/userlogin}" method="post">
            用户名:<input name="user"/><br>
            密码:<input name="pwd"><br/>
            <input type="checkbox" name="remeberme"/>记住我<br/>
            <input type="submit" value="登陆">
        </form>
    </div>
</body>
</html>

4、测试,也是和使用Spring定义的登录页面一样的效果(注:记得welcome.html中的登录a标签要换成/userlogin

v2-2a111a39c437c8685866b3c5be73f353_b.jpg

v2-2ddac9f109d889ecf187e56b9b084d8e_b.jpg

v2-c4bb094b4cfdeb8af6a244699dd51e28_b.jpg
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值