一、原理分析
前台的登录请求发送到后端后会由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_11.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 aspectjweaver1.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 junit4.12 test javax.servlet javax.servlet-api3.1.0 provided javax.servlet.jsp jsp-api2.0 provided jstl jstl1.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-spring1.3.0 c3p0 c3p00.9.1.2 jar compile com.github.pagehelper pagehelper5.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-api1.0 com.fasterxml.jackson.core jackson-databind2.9.7 com.fasterxml.jackson.core jackson-core2.9.7 org.projectlombok lombok1.16.16 org.apache.tomcat.maven tomcat7-maven-plugin2.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 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
如果需要查看示例工程的具体代码,可以点击下方的链接在码云上查看
示例工程地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。



