详解使⽤SpringSecurity进⾏⾃动登录验证
在之前的博客使⽤SpringMVC创建Web⼯程并使⽤SpringSecurity进⾏权限控制的详细配置⽅法中,我们描述了如何配置⼀个基于SpringMVC、SpringSecurity框架的⽹站系统。在这篇博客中,我们将继续描述如何使⽤Spring Security进⾏登录验证。
总结⼀下Spring Security的登录验证关键步骤:
1、在数据库中建好三张表,即users、authorities和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等。
jquery怎么进行验证⼆、配置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="/schema/security"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:beans="/schema/beans"
xsi:schemaLocation="/schema/beans
/schema/beans/spring-beans-4.0.xsd
/schema/security
/schema/security/spring-security-4.0.xsd">
<!-- 配置为none的不经过任何spring的过滤器 -->
<http pattern="/resources/**" security="none" />
<http pattern="/l" 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="t.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.pto.bcrypt.BCryptPasswordEncoder" />
</beans:beans>
注意,这⾥定义了<beans:bean name="bcryptEncoder"
class="org.pto.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 = de(password);
Object[] param = {email, pwd};
//插⼊authorities表的语句
String addAuthority = "insert into authorities(username,authority) values(?,'ROLE_USER')";
Object[] authorityParam = {email};
int rows = 0;
try {
rows = QueryRunner().update(addUser, param);
rows += QueryRunner().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 = de(rawPassword);
return encoderPassword;
}
这样,⽤户就可以注册了。注册好了就可以使⽤登录功能了。
总结⼀下Spring Security的登录验证关键步骤:
1、在数据库中建好三张表,即users、authorities和persistent_logins三个。注意字段的定义,不能少,可以多,名字必须按规定来。
2、在Spring Security的配置⽂件中,配置好登录跳转的页⾯,登录处理的页⾯和加密情况。
3、在前台的jsp页⾯中,登录的字段必须和后台users表中的⼀致,⼀般都是username和password。
4、注册页⾯必须⾃⼰写,注册的处理也要⾃⼰写。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论