Spring boot 用户自定义访问控制,自定义登录页面,退出,用户信息获取

Posted 流星蝴蝶没有剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring boot 用户自定义访问控制,自定义登录页面,退出,用户信息获取相关的知识,希望对你有一定的参考价值。

浅看

用户自定义访问控制,自定义登录页面,退出,用户信息获取*

一、代码实现 Security 认证

1. 登录 + 访问控制

  • 依赖
<!--        spring security-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

实现登录不同的身份访问不同的留言板功能

登录界面代码:

登录普通用户


登录VIP

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="template::meta">
</head>
<!--    需要下载下面,不然会被替换。 -->
<title th:text="#page.login.title"></title>
<!--        自定义样式-->
<link th:href="@/css/login.css" rel="stylesheet">

<body>
<div class="container">
    <div class="text-center">
        <form class="form-signin" method="get" action="/toLogin">
            <h2 class="form-signin-heading" th:text="#page.login.button">登录</h2>
            <div th:if="$param.hasError" class="alert alert-danger" role="alert">登录失败</div>
            <div th:if="$param.toOut" class="alert alert-danger" role="alert">退出成功</div>
            <p>
                <label for="customer" class="sr-only" th:text="#page.login.username">用户名</label>
                <input type="text" id="customer" name="customer" class="form-control"
                       th:placeholder="#page.login.username">
            </p>
            <p>
                <label for="password" class="sr-only" th:text="#page.login.password">密码</label>
                <input type="password" id="password" name="password" class="form-control"
                       th:placeholder="#page.login.password">
            </p>
            <input name="_csrf" type="hidden" th:value="$_csrf.token"/>
            <button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#page.login.button">
                登录
            </button>
        </form>
    </div>

    <!--  footer 片段包含-->
    <div th:insert="template::footer"></div>
</div>
</body>

</html>
  • 控制器
    @GetMapping(value = "/toLogin")
    public String toLogin(Model model) 
        model = this.foot(model);
        return "login/myLogin";
    
  • 重写父类

package wx0725.top.config;

import org.springframework.beans.factory.annotation.Autowired;
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;
import wx0725.top.service.UserDetailsServiceImpl;

import javax.sql.DataSource;

/**
 * @author WEN
 * @version 1.0
 * @description: Wen Xuan
 * @date 2021/5/7 下午 19:42
 * @link http://wx0725.top
 */
@EnableWebSecurity
// 上面一个注解中包含下面三个注解
//@Import
//@EnableGlobalAuthentication
//@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 

        //        下面的内容在自己拓展是使用,暂时用不到
    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.authorizeRequests()
                .antMatchers("/login/**", "/getUserSession").permitAll()

                .antMatchers("/css/**", "/img/**", "/fonts/**", "/js/**").permitAll()

                .antMatchers("/common/**", "/api/common/**").hasRole("common")
                .antMatchers("/vip/**", "/api/vip/**").hasRole("vip")

                .anyRequest().authenticated();

        http.formLogin()
                .loginPage("/toLogin").permitAll()
                .usernameParameter("customer")
                .passwordParameter("password")
                .failureUrl("/toLogin?hasError");

        http.logout()
                .logoutSuccessUrl("/toLogin?toOut");
    



  • 测试
    登录vip测试

    访问其他权限的页面

2. 退出

               
<form th:method = "post" th:action = "@/logout">
                <input type = "submit" th:value = "退出" name = "logout">
            </form>

3. 信息获取

 @GetMapping("getUserSession")
    @ResponseBody
    public String getUerSession(HttpSession httpSession) 
        Enumeration<String> names = httpSession.getAttributeNames();
        String re = null;
        while (names.hasMoreElements()) 
            String name = names.nextElement();
            SecurityContextImpl securityContext = (SecurityContextImpl) httpSession.getAttribute(name);
            re += name + "<br>";
            re += securityContext + "<br>";

            Authentication authentication = securityContext.getAuthentication();
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            re += userDetails + "<br>";
            re += userDetails.getUsername() + "<br>" + "<br>";
        
        return re;
    

登录两个用户查看效果


三、问题

1. 在访问页面时没有css样式

重写 WebSecurityConfigurerAdapter

    @Override
    public void configure(WebSecurity web) throws Exception 
        web.ignoring().antMatchers("/css/**", "/js/**", "/img/**", "/fonts/**", "/favicon.ico");
    

2. 使用Security 认证,ajax 通过 post 提交数据时报错 403

推荐:登录方式-token登录和csrfToken登录

在看课本上的代码时,会发现有一行 type=hidden的一个input标签,然后就试着删除试试,会发现登录页面正常访问,点击登录正常,为什么呢?因为上课老师说过,在写的控制器时必须使用GetMapping

开始:

  • 首先写一个控制器,提供页面访问

  • 访问

  • POST 登录



看到两个_csrf,一个是自己手写的,另一个是 th:method 之后

在删除了th:action、th:method前面的th之后,会发现少了一个,说明那个token是th模板自动生成的。

也就是说 _csrf这个参数是在使用 post 请求时必须携带的,所以在使用 ajax 请求时,必须将这个参数带进去。

  1. 如果没有th:action 或者 th:method,添加
<input name = "_csrf" id = "_csrf" type = "hidden" th:value = "$_csrf.token" />
  1. ajax data:
_csrf: $("#_csrf").val(),

3. 获取用户信息的三种方法

推荐:Security 获取当前会话的三种方法

以上是关于Spring boot 用户自定义访问控制,自定义登录页面,退出,用户信息获取的主要内容,如果未能解决你的问题,请参考以下文章

如何为 ZuulException 自定义 Spring Boot 控制器 API 响应

spring security +spring boot 自定义 403 页面

测试开发专题:spring-boot自定义返回参数校验错误信息

测试开发专题:spring-boot自定义返回参数校验错误信息

Spring Boot 测试自定义错误控制器

Spring Boot中Spring MVC的整合支持