Spring Security 实现记住我

开篇一张图,道理全靠悟。

示例如下:

1.    新建Maven项目  remember_me

2.   pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.java</groupId>
    <artifactId>remember_me</artifactId>
    <version>1.0.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

    <dependencies>

        <!-- Spring Boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.0.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.11</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 热部署 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
            <version>1.2.8.RELEASE</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

3.   RememberMeStarter.java

package com.java;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * <blockquote><pre>
 *
 * 主启动类
 *
 * </pre></blockquote>
 *
 * @author Logan
 *
 */
@SpringBootApplication
public class RememberMeStarter {

    public static void main(String[] args) {
        SpringApplication.run(RememberMeStarter.class, args);
    }

}

4.   ApplicationContextConfig.java

package com.java.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * 配置文件类
 *
 * @author Logan
 *
 */
@Configuration
public class ApplicationContextConfig {

    /**
     * <blockquote><pre>
     *
     * 配置密码编码器,Spring Security 5.X必须配置,否则登录时报空指针异常
     *
     * </pre></blockquote>
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

5.   RepositoryConfig.java

package com.java.config;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/**
 * 数据库相关配置
 *
 * @author Logan
 *
 */
@Configuration
public class RepositoryConfig {

    @Bean
    public PersistentTokenRepository tokenRepository(DataSource dataSource) {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // tokenRepository.setCreateTableOnStartup(true); // 第一次启动时可使用此功能自动创建表,第二次要关闭,否则表已存在会启动报错
        return tokenRepository;
    }

}

6.   LoginConfig.java

package com.java.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

/**
 * 登录相关配置
 *
 * @author Logan
 *
 */
@Configuration
public class LoginConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private PersistentTokenRepository tokenRepository;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()

                // 设置不需要授权的请求
                .antMatchers("/js/*", "/login.html").permitAll()

                // 其它任何请求都需要验证权限
                .anyRequest().authenticated()

                // 设置自定义表单登录页面
                .and().formLogin().loginPage("/login.html")

                // 设置登录验证请求地址为自定义登录页配置action ("/authentication/form")
                .loginProcessingUrl("/authentication/form")

                // 添加记住我功能
                .and().rememberMe().tokenRepository(tokenRepository)

                // 有效期为两周
                .tokenValiditySeconds(3600 * 24 * 14)

                // 设置UserDetailsService
                .userDetailsService(userDetailsService)

                // 暂时停用csrf,否则会影响验证
                .and().csrf().disable();
    }

}

7.  src/main/resources  下文件如下

8.   application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.32.10:3306/security?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.dbcp2.initial-size=5
spring.datasource.dbcp2.max-total=20

9.   login.html

<!DOCTYPE html>
<html>

    <head>
        <title>登录</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    </head>

    <body>

        <!--登录框-->
        <div align="center">
            <h2>用户自定义登录页面</h2>
            <fieldset style="width: 300px;">
                <legend>登录框</legend>
                <form action="/authentication/form" method="post">
                    <table>
                        <tr>
                            <th>用户名:</th>
                            <td><input name="username" /> </td>
                        </tr>
                        <tr>
                            <th>密码:</th>
                            <td><input type="password" name="password" /> </td>
                        </tr>
                        <tr>
                            <th>记住我:</th>
                            <td><input type="checkbox" name="remember-me" value="true" checked="checked" /></td>
                        </tr>
                        <tr>
                            <th></th>
                            <td></td>
                        </tr>
                        <tr>
                            <td colspan="2" align="center"><button type="submit">登录</button></td>
                        </tr>
                    </table>
                </form>
            </fieldset>

        </div>

    </body>

</html>

10.   main.html

<!DOCTYPE html>
<html>

    <head>
        <title>首页</title>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
        <script>
            function getHostMessage() {
                $.ajax({
                    type: "get",
                    url: "/getHostMessage",
                    async: true,
                    success: function(data) {
                        $("#msg").val(JSON.stringify(data));
                    }
                });
            }
        </script>
    </head>

    <body>

        <div>
            <h2>首页</h2>
            <table>
                <tr>
                    <td><button onclick="getHostMessage()">获取主机信息</button></td>
                </tr>
            </table>

        </div>

        <!--响应内容-->
        <div>
            <textarea id="msg" style="width: 800px;height: 800px;"></textarea>
        </div>

    </body>

</html>

11.   js/jquery-3.3.1.min.js 可在官网下载

https://code.jquery.com/jquery-3.3.1.min.js

12.   创建数据库

DROP DATABASE IF EXISTS security;
CREATE DATABASE security;
USE security;
create table persistent_logins (
    username varchar(64) not null,
    series varchar(64) primary key,
    token varchar(64) not null,
    last_used timestamp not null
);

13.   运行 RememberMeStarter.java , 启动测试

浏览器输入首页  http://localhost:8080/main.html

地址栏自动跳转到登录页面,如下:

输入如下信息:

User:Logan

Password:123456

单击【登录】按钮,自动跳转到首页。

观察数据库,此时自动生成一条记录,username字段值为登录时使用用户名,记住我Token信息已生成。

如下所示:

测试【记住我】 功能是否生效

关闭浏览器重新打开,或者关闭系统重新启动,再次访问首页,页面不再跳转到登录页,直接显示首页信息。

如下所示:

.

原文地址:https://www.cnblogs.com/jonban/p/rememberMe.html

时间: 2024-11-09 04:04:51

Spring Security 实现记住我的相关文章

Spring Security应用开发(16)基于表达式的访问控制

1.1.1. 通用表达式 Spring Security 使用基于Spring EL的表达式来进行访问控制.内置的表达式如下表所示: 表达式 描述 hasRole(role) 当前主体(principal)是否支持role角色.支持则返回true hasAnyRole(role1,role2) 当前主体是否支持role1,role2中的任意一个角色. hasAuthority(authority) 跟hasRole(role)相似. hasAnyAuthority(authority1,auth

Java Web系列:Spring Security 基础

Spring Security虽然比JAAS进步很大,但还是先天不足,达不到ASP.NET中的认证和授权的方便快捷.这里演示登录.注销.记住我的常规功能,认证上自定义提供程序避免对数据库的依赖,授权上自定义提供程序消除从缓存加载角色信息造成的角色变更无效副作用. 1.基于java config的Spring Security基础配置 (1)使用AbstractSecurityWebApplicationInitializer集成到Spring MVC 1 public class Securit

spring security使用hibernate进行查询数据库验证

前面查询数据库采用的都是jdbc方式,如果系统使用的是hibernate,该如何进行呢,下面就是实现步骤,关键还是实现自定义的UserDetailsService 项目结构如下: 使用hibernate,pom.xml文件如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLo

用spring security实现简单的登陆和权限角色控制

 随笔简介 spring版本:4.3.2.RELEASE+spring security 版本:4.1.2.RELEASE(其它不做说明) 所展示内容全部用注解配置 springmvc已经配置好,不作说明 会涉及到springmvc,spel,el的东西,不熟悉的同学可以先去看一下这方面内容,特别是springmvc 首先想一下,登陆需要什么,最简单的情况下,用户名,密码,然后比对数据库,如果吻合就跳转到个人页面,否则回到登陆页面,并且提示用户名密码错误.这个过程中应该还带有权限角色,并且贯穿整

Spring Security教程系列(一)基础篇

第 1 章 一个简单的HelloWorld 第 1 章 一个简单的HelloWorld Spring Security中可以使用Acegi-1.x时代的普通配置方式,也可以使用从2.0时代才出现的命名空间配置方式,实际上这两者实现的功能是完全一致的,只是新的命名空间配置方式可以把原来需要几百行的配置压缩成短短的几十行.我们的教程中都会使用命名空间的方式进行配置,凡事务求最简. 1.1. 配置过滤器 为了在项目中使用Spring Security控制权限,首先要在web.xml中配置过滤器,这样我

第一章 Spring Security是什么?

1. 介绍 1.1 Spring Security是什么? Spring Security是一个强大的和高度可定制的身份验证和访问控制框架. 它是保证基于spring的应用程序安全的实际标准. 1.2 Spring Security 的一些能实现的具体的一些功能特性 HTTP基本身份验证header(IETF RFC-based标准) HTTP摘要式身份验证头(IETF RFC-based标准) HTTP X. 509客户端证书交换(IETF RFC-based标准) LDAP(一种很常见的方法

基于javaConfig和注解配置Spring Security

Spring Security 借助一系列Servlet Filter 来提供安全性功能,但是借助Spring的小技巧,我们只需要配置一个Filer就可以了,DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的工作并不多,只是将工作委托给一个javax.servlet.Filter 的实现类,这个实现类作为一个bean注册再Spring应用的上下文中. 如果了解过用xml配置spring security的朋友就知道,用基于xml配置Spring Se

[转]Spring Security学习总结一

[总结-含源码]Spring Security学习总结一(补命名空间配置) Posted on 2008-08-20 10:25 tangtb 阅读(43111) 评论(27)  编辑  收藏 所属分类: Spring .Spring Security Spring Security学习总结一 在认识Spring Security之前,所有的权限验证逻辑都混杂在业务逻辑中,用户的每个操作以前可能都需要对用户是否有进行该项 操作的权限进行判断,来达到认证授权的目的.类似这样的权限验证逻辑代码被分散

Spring Security应用开发(14) 重要概念之授权相关概念

1.1.1. Secure Object Secure Object指的是一个Method Invovation 或者一个URL资源. 1.1.2. GrantedAuthority GrantedAuthority用于表达指定的用户获得的权限(即角色名称). public interface GrantedAuthority extends Serializable { //返回一个表达已经经过授权的字符串. //如果不符合授权条件则返回null. String getAuthority();