这里有新鲜出炉的精品教程, 程序狗速度看过来!
Spring Framework 开源 j2ee 框架
Spring 是什么呢? 首先它是一个开源的项目, 而且目前非常活跃; 它是一个基于 IOC 和 AOP 的构架多层 j2ee 系统的框架, 但它不强迫你必须在每一层 中必须使用 Spring, 因为它模块化的很好, 允许你根据自己的需要选择使用它的某一个模块; 它实现了很优雅的 MVC, 对不同的数据访问技术提供了统一的接口, 采用 IOC 使得可以很容易的实现 bean 的装配, 提供了简洁的 AOP 并据此实现 Transcation Managment, 等等
本篇文章主要介绍了详解使用 Spring Security 进行自动登录验证, 非常具有实用价值, 需要的朋友可以参考下
在之前的博客使用 SpringMVC 创建 web 工程并使用 SpringSecurity 进行权限控制的详细配置方法 中, 我们描述了如何配置一个基于 SpringMVCSpringSecurity 框架的网站系统在这篇博客中, 我们将继续描述如何使用 Spring Security 进行登录验证
总结一下 Spring Security 的登录验证关键步骤:
1 在数据库中建好三张表, 即 usersauthorities 和 persistent_logins 三个注意字段的定义, 不能少, 可以多, 名字必须按规定来
2 在 Spring Security 的配置文件中, 配置好登录跳转的页面, 登录处理的页面和加密情况
3 在前台的 jsp 页面中, 登录的字段必须和后台 users 表中的一致, 一般都是 username 和 password
4 注册页面必须自己写, 注册的处理也要自己写
一创建数据表
使用 Spring Security 进行登录验证, 需要我们在数据库中建好相应的表, 并且字段要和 Spring Security 内置的字段一致主要有 3 张表需要建立一是 users 表, 包含用户名和密码以及用户状态的表; 第二个是 authorities 表, 表明该用户角色的, 方便做角色控制, 比如是 ROLE_USER 还是 ROLE_ADMIN(比如 admin 页面可能需要用户的 ROLE_ADMIN 权限, 而 ROLE_USER 权限无法登录这个管理页面); 最后一个是 persistent_logins 表, 是登录状态的记录表, 主要用来提供支持记住我功能的三张表的创建语句如下:
- #create users table
- CREATE TABLE `users` (
- `username` varchar(100) NOT NULL,
- `password` varchar(100) NOT NULL,
- `enabled` tinyint(1) NOT NULL DEFAULT '1',
- UNIQUE KEY `account` (`username`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- #create authorities table
- CREATE TABLE `authorities` (
- `username` varchar(50) NOT NULL,
- `authority` varchar(50) DEFAULT NULL,
- PRIMARY KEY (`username`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- #create persistent_logins table
- CREATE TABLE `persistent_logins` (
- `username` varchar(64) NOT NULL,
- `series` varchar(64) NOT NULL,
- `token` varchar(64) NOT NULL,
- `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- PRIMARY KEY (`series`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
记住, 这三张表字段一定要至少包含以上字段这样 Spring Security 才能识别但是, 我们也可以额外添加一些字段, 比如在 users 中添加 uid 等
二配置 Spring Security 的权限控制
配置 Spring Security 的控制信息就是配置哪些页面需要登录的用户才能访问, 登录的页面是那一个, 登陆成功跳转到哪里等以如下配置为例: 所有的 js 等在 resources 文件夹下的内容都不需要经过过滤器, 因为这些都是静态资源而首页 (/), 登录页(/signin) 注册页 (/register) 等不需要用户登录, 但是需要经过过滤器 (因为我们可能需要获取未登录用户的一些信息) 两种配置方式如下所示最后我们使用 < form-login login-page="/signin" authentication-failure-url="/signin?login_error" default-target-url="/query"/>这个配置来说明登录页面是 / signin, 即所有需要用户登录的页面, 在用户未登录情况下需要跳转到这个页面, 让用户登录 authentication-failure-url 配置的是用户登录失败的页面, 而 default-target-url 是配置用户登录成功后跳转的页面
- <?xml version="1.0" encoding="UTF-8" ?>
- <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
- http://www.springframework.org/schema/security
- http://www.springframework.org/schema/security/spring-security-4.0.xsd">
- <!-- 配置为 none 的不经过任何 spring 的过滤器 -->
- <http pattern="/resources/**" security="none" />
- <http pattern="/sitemap.xml" security="none" />
- <http pattern="/favicon.ico" security="none" />
- <!-- 配置为 permitAll 允许用户访问, 但依然经过过滤器处理 -->
- <http auto-config="true" use-expressions="true">
- <intercept-url pattern="/" access="permitAll" />
- <intercept-url pattern="/index*" access="permitAll" />
- <intercept-url pattern="/signin*" access="permitAll" />
- <intercept-url pattern="/login*" access="permitAll" />
- <intercept-url pattern="/register*" access="permitAll" />
- <intercept-url pattern="/invalidsession*" access="permitAll" />
- <intercept-url pattern="/404*" access="none" />
- <form-login login-page="/signin" authentication-failure-url="/signin?login_error"
- default-target-url="/query" />
- <logout logout-success-url="/query" delete-cookies="JSESSIONID" />
- <intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
- <intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"
- />
- <csrf disabled="true" />
- <access-denied-handler error-page="/403" />
- <remember-me data-source-ref="dataSource" token-validity-seconds="1209600"
- remember-me-parameter="remember-me" />
- <session-management invalid-session-url="/">
- <concurrency-control max-sessions="1" />
- </session-management>
- </http>
- <authentication-manager erase-credentials="false">
- <authentication-provider>
- <password-encoder ref="bcryptEncoder" />
- <jdbc-user-service data-source-ref="dataSource" />
- </authentication-provider>
- </authentication-manager>
- <beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
- <beans:property name="basenames">
- <beans:list>
- <beans:value>
- classpath:myMessages
- </beans:value>
- </beans:list>
- </beans:property>
- </beans:bean>
- <beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"
- />
- </beans:beans>
注意, 这里定义了 < beans:bean name="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />, 表明登录的时候会对密码进行加密, 那么后面我们写注册页面的时候必须要对密码加密之后才能存入数据库
三创建登录 / 注册的页面
这里属于前台的范畴, 如果我们要使用 Spring Security 自带的验证方法, 需要在前台也配置一样的信息来获取验证需要的字段, 如用户名和密码所以这里也是需要注意的地方具体的页面核心代码如下(我们的页面使用了 Bootstrap 的前端工具, 所以要引入 bootrap 和 jquery 等外部样式和脚本语言才会正常显示, 但是这些显示不会影响功能, 核心的字段不变即可):
- <div class="container">
- <!-- 页面切换代码 -->
- <ul class="nav nav-tabs" id="loginTab" role="tablist">
- <li class="nav-item">
- <a class="nav-link active" id="home-tab" data-toggle="tab" href="#login" rel="external nofollow"
- role="tab" aria-controls="home" aria-expanded="true">登录</a>
- </li>
- <li class="nav-item">
- <a class="nav-link" id="home-tab" data-toggle="tab" href="#register" rel="external nofollow"
- role="tab" aria-controls="home" aria-expanded="true">注册</a>
- </li>
- </ul>
- <div class="tab-content" id="myTabContent">
- <!-- 登录页面 -->
- <div id="login" class="tab-pane fade show active" role="tabpanel" aria-labelledby="login-tab">
- <form class="form-signin" action="login" method="post">
- <label for="username" class="sr-only">Email address</label>
- <input type="email" name="username" id="username" class="form-control" placeholder="邮件地址">
- <label for="password" class="sr-only">Password</label>
- <input type="password" name="password" id="password" class="form-control" placeholder="密码">
- <button class="btn btn-lg btn-primary btn-block" type="submit">点击登录</button>
- </form>
- </div>
- <!-- 注册页面 -->
- <div id="register" class="tab-pane fade" role="tabpanel" aria-labelledby="register-tab">
- <div id="register_attention_alert_reg"></div>
- <form class="form-signin" onsubmit="return register()" method="post">
- <label for="registerEmail" class="sr-only">Email address</label>
- <input type="email" id="registerEmail" name="registerEmail" class="form-control" placeholder="邮件地址">
- <label for="registerPassword" class="sr-only">Password</label>
- <input type="password" name="password" id="registerPassword" class="form-control" placeholder="密码">
- <label for="inputPassword2" class="sr-only">Password</label>
- <input type="password" id="inputPasswordForRegister2" class="form-control" placeholder="请再次输入密码">
- <button class="btn btn-lg btn-primary btn-block" onclick="submit">点击注册</button>
- </form>
- </div>
- </div>
- </div>
这里有两个 Tab 页代码, 一个是登录 Tab 一个是注册 Tab 主要是登录的 Tab 要和 Spring Security 一致, 即登录的处理应当是 login, 即 action="login", 用户名的 ID 和 name 应该是 username, 而密码的应该是 password, 即提交给登录验证的两个参数应当是 username 和 password, 处理的请求页是 login
四创建注册后台, 定义登录处理
当登录注册页面做好之后, 需要定义一下处理请求, 即跳转的定义然后只要写注册的后台就行了注意一点, Spring Security 的注册处理需要自己写个后台用户提交注册后, 我们需要把用户名和密码插入到数据库中, 又一点注意了, 由于我们之前配置了密码的加密, 所以用户注册在插入数据库之前需要加密, 否则后面无法验证通过在注册用户的时候, 我们需要更新 users 表的信息和 authorities 表信息, 前者插入用户名和密码, 并使得 enabled=1(这个字段表示用户是否正常,=0 的话, 状态就是锁定的)在 authorities 中要写入用户对应的角色 (权限) 用户注册的时候密码加密的关键代码如下:
- // 插入 users 表的语句
- String addUser = "insert into users(username,password) values(?,?)";
- // 对密码参数进行加密
- String pwd = SpringSecurityUtil.encode(password);
- Object[] param = {email, pwd};
- // 插入 authorities 表的语句
- String addAuthority = "insert into authorities(username,authority) values(?,'ROLE_USER')";
- Object[] authorityParam = {email};
- int rows = 0;
- try {
- rows = MyQueryRunnerUtil.getQueryRunner().update(addUser, param);
- rows += MyQueryRunnerUtil.getQueryRunner().update(addAuthority, authorityParam);
- } catch (SQLException e) {
- e.printStackTrace();
- }
加密的代码如下:
- /**
- * BCrypt 加密(适用于注册时密码加密)
- *
- * @param rawPassword 明文密码
- * @return encoderPassword 密文密码, 长度为 60
- */
- public static String encode(String rawPassword) {
- // 调用 spring security 的 BCrypt 加密
- BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
- String encoderPassword = encoder.encode(rawPassword);
- return encoderPassword;
- }
这样, 用户就可以注册了注册好了就可以使用登录功能了
总结一下 Spring Security 的登录验证关键步骤:
1 在数据库中建好三张表, 即 usersauthorities 和 persistent_logins 三个注意字段的定义, 不能少, 可以多, 名字必须按规定来
2 在 Spring Security 的配置文件中, 配置好登录跳转的页面, 登录处理的页面和加密情况
3 在前台的 jsp 页面中, 登录的字段必须和后台 users 表中的一致, 一般都是 username 和 password
4 注册页面必须自己写, 注册的处理也要自己写
来源: http://www.phperz.com/article/18/0313/353292.html