Spring Security自定义登陆界面和密码验证逻辑

maven依赖

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

创建配置文件处理跳转拦截等功能以及密码比对功能

package com.example.demo2.demos.web1;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDateService userDateService;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         *  1. 允许访问路径"/"或者"/home",而不需要登录。
         *  除过"/"或者"/home",其他页面都需要登录。
         *  2. 表单登录,路径是"/login",允许所有用户都可以发起登录操作
         *  3. 允许所有用户都可以退出登录
         */
        http
             .formLogin()
                .loginPage("/login.html")    //登录页面设置
                //配置从前端传递过来的用户名和密码字段名
                //.usernameParameter("name")
				//.passwordParameter("password")
                .loginProcessingUrl("/user/login")   //点击登录后访问的路径
                .defaultSuccessUrl("/index.html").permitAll()   //登录成功后跳转路        
                    径,permitAll表示无条件进行访问
                .and()
             .authorizeRequests()
                .mvcMatchers("/","/user/login").permitAll() //设置不需要认证可以直接访问的 
                 路径
                .anyRequest().authenticated()
                //关闭csrf
                .and().csrf().disable()
             .logout()
                .logoutUrl("/logout")
                .logoutSuccessUrl("/login?logout")
                .permitAll();
    }
    //密码加密
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    //密码比对
    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDateService);
    }
}

创建userservice

package com.example.demo2.demos.web1;

import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

/**
 * @author FAN BOY
 * @version 1.0
 * @date 2020/7/20 14:22
 */
@Service
public class UserDateService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        //这是通过username查询获取一组数据将获得的数据传给security的User
        //sql语句自己写
        com.example.demo2.demos.web2.User user =new com.example.demo2.demos.web2.User("admin",passwordEncoder.encode("123"),12);
        //这里我们使用静态类来模拟通过数据库获取的user类
//        if (user == null) {
//            throw new UsernameNotFoundException("该用户不存在!");
//        }
        //把获得的账号密码传给security的User
        //注意此时的User是security自带的的User类,第一个参数为用户名,第
二个为密码,一般来说我们从数据库获取的为加密后的密码,所以我们通过上面配置
文件的密码加密自己进行加密,第三个为权限角色,我没有做处理
      return new User(user.getUsername(),user.getPassword(),new ArrayList<>());
    }
}

自定义登陆界面login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="/user/login" method="post">
//注意用户名和密码 为username和password,security默认为这
两个字段,如果你要用其他的名称,需要在第一个配置文件中的
loginForm中进行配置
    用户名:<input type="text" name="username"/><br>
    密码:<input type="password" name="password"/><br>
    <input type="submit" value="登录"/>
</form>
</body>
</html>

上面的UserDateService 中我们固定返回一个用户名密码为admin 123的user类

然后security的configure(AuthenticationManagerBuilder auth)进行密码对比,注意这里只是比较密码,因为你既然返回user类了就说明你的username是存在的,(小问题,一般来说不会有问题因为我是固定返回的一个类,我在前端只要是密码输入正确就能登陆~)

上面就实现了一个自定义登陆界面以及密码验证的基本功能的(由于公司电脑不让本地装数据库,就用静态类代替了,如果要链接数据库也就是添加一个查询数据库方法而已)。

相关推荐
手握风云-2 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
Amd7945 分钟前
Nuxt.js 应用中的 webpack:compiled 事件钩子
前端·webpack·开发·编译·nuxt.js·事件·钩子
生椰拿铁You14 分钟前
09 —— Webpack搭建开发环境
前端·webpack·node.js
喵叔哟22 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
狸克先生25 分钟前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
尘浮生28 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
baiduopenmap40 分钟前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
loooseFish1 小时前
小程序webview我爱死你了 小程序webview和H5通讯
前端
不是二师兄的八戒1 小时前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php
菜牙买菜1 小时前
让安卓也能玩出Element-Plus的表格效果
前端