目录
- spring security 使用数据库中的账户和密码认证
- 一、原理分析
- 二、代码实现
- 1.新建一个javaWeb工程
- 2.用户认证的实现
- 3.测试
- 三、总结
spring security 使用数据库中的账户和密码认证
示例工程地址
一、原理分析
前台的登录请求发送到后端后会由spring security进行拦截,即controller层由框架自己提供。这样用户名和密码的认证就需要在service层完成,所以框架需要在service层获取到我们自己的数据库账号信息。
spring security 提供了一个接口 UserDetailsService 来让用户提供账号和密码,其内容如下
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
用户实现这个接口中的loadUserByUsername方法,通过数据库中查询的账号和密码构造一个UserDetails对象返回给spring security,然后框架自己完成认证操作。
其中UserDetails也是一个接口,spring security用它来封装当前进行认证的用户信息
public interface UserDetails extends Serializable {
Collection extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
spring security 自己提供了一个实现类我们可以直接使用,以下是User中的部分代码
public class User implements UserDetails, CredentialsContainer {
private String password;
private final String username;
private final Set authorities;
private final boolean accountNonExpired; //帐户是否过期
private final boolean accountNonLocked; //帐户是否锁定
private final boolean credentialsNonExpired; //认证是否过期
private final boolean enabled; //帐户是否可用
}
所以,使用数据库完成认证的关键就是实现UserDetailsService接口,并在loadUserByUsername方法中封装一个框架需要的UserDetails对象,即User对象返回给框架,由框架完成后续的认证操作。
同时需要在spring security的配置文件中指定要用来认证的userService 的bean
二、代码实现
1.新建一个javaWeb工程
新建一个javaweb工程,导入相关依赖,pom文件的内容如下
pom文件
4.0.0
com.lyy
spring_security_1
1.0-SNAPSHOT
war
spring_security_1 Maven Webapp
http://www.example.com
UTF-8
5.0.2.RELEASE
1.6.6
1.2.12
5.1.6
3.4.5
5.0.1.RELEASE
org.aspectj
aspectjweaver
1.6.8
org.springframework
spring-aop
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-context-support
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-test
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-tx
${spring.version}
junit
junit
4.12
test
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet.jsp
jsp-api
2.0
provided
jstl
jstl
1.2
log4j
log4j
${log4j.version}
org.slf4j
slf4j-api
${slf4j.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
mysql
mysql-connector-java
${mysql.version}
org.mybatis
mybatis
${mybatis.version}
org.mybatis
mybatis-spring
1.3.0
c3p0
c3p0
0.9.1.2
jar
compile
com.github.pagehelper
pagehelper
5.1.2
org.springframework.security
spring-security-web
${spring.security.version}
org.springframework.security
spring-security-config
${spring.security.version}
org.springframework.security
spring-security-core
${spring.security.version}
org.springframework.security
spring-security-taglibs
${spring.security.version}
javax.annotation
jsr250-api
1.0
com.fasterxml.jackson.core
jackson-databind
2.9.7
com.fasterxml.jackson.core
jackson-core
2.9.7
org.projectlombok
lombok
1.16.16
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
80
/
UTF-8
tomcat7
在web.xml中配置spring security的过滤器
web.xml
spring security 01
contextConfigLocation
classpath:spring-security.xml,classpath*:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
springSecurityFilterChain
org.springframework.web.filter.DelegatingFilterProxy
springSecurityFilterChain
/*
characterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
characterEncodingFilter
/*
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
整合spring和mybatis,spring的配置文件applicationContext.xml
spring配置文件
spring security配置文件
spring security的配置文件的内容,spring-security.xml
在这个配置文件中要注意的是配置用来认证的userService Bean
创建登录页面和登录失败的页面login.html,failed.html
2.用户认证的实现
新建一个IUserService接口继承UserDetailsService
package com.lyy.service;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface IUserService extends UserDetailsService {
}
实现类如下
@Service("userService")
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userDao.findByUsername(username);
User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getRoles());
return user;
}
/*给用户赋值角色信息*/
private List getRoles(){
List list=new ArrayList();
list.add(new SimpleGrantedAuthority("ROLE_USER"));
list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return list;
}
}
其中在loadUserByUsername方法中完成查询数据库信息,封装成框架需要的用户信息。
注意 :
UserInfo是封装数据库用户信息的实体类
getRoles用来给用户赋角色信息,spring security认证时用户必须有角色信息,角色信息可以从数据库中查询,在这里直接在代理中写固定值来示意。
用户密码中拼接的"{noop}"字符串是因为我们没有对密码进行加密,所以要告诉框架认证密码时不需要加密。
3.测试
启动工程,访问localhost,会跳转到登录页面,输入数据库中存在的账户和密码就会登录成功并跳转到首页index.html
三、总结
使用数据库完成认证的关键就是实现UserDetailsService接口,并在loadUserByUsername方法中封装一个框架需要的UserDetails对象,即User对象返回给框架,由框架完成后续的认证操作。
同时需要在spring security的配置文件中指定要用来认证的userService 的bean,即实现了loadUserByUsername方法的userService
如果需要查看示例工程的具体代码,可以点击下方的链接在码云上查看
示例工程地址