文章目录
1. 前言
通过前面的知识,我们已经能够简单的使用spring-security
,并且整合到ssm框架中。当然,前面的例子中我们都是在内存中构造的用户进行验证的,也就是下面这行代码:
<!-- 在内存中构造用户们 -->
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user" authorities="ROLE_USER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
实际的开发过程中,我们都是从数据库中读取的数据,接下来我们介绍如何实现。
2. UserDetails与UserDetailsService
在Spring Security中如果想要使用数据进行认证操作,有很多种操作方式,这里我们介绍使用UserDetails、 UserDetailsService来完成操作。
2.1 UserDetails及其实现类User
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
UserDetails是一个接口,我们可以认为UserDetails
作用是于封装当前进行认证的用户信息,相当于之前构造于内存中的用户。但由于其是一个接口,所以我们可以对其进行实现,也可以使用Spring Security内部提供的一个UserDetails的实现类User
来完成操作 。
以下是User类的部分代码:
public class User implements UserDetails, CredentialsContainer {
private final String username; //用户登入名
private String password; //用户登入密码
private final Set<GrantedAuthority> authorities; //用户所基本的权限,比如:ROLE_USER
private final boolean accountNonExpired; //帐户是否过期
private final boolean accountNonLocked; //帐户是否锁定
private final boolean credentialsNonExpired; //认证是否过期
private final boolean enabled; //帐户是否可用
}
2.2 UserDetailsService
UserDetailsService:
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
UserDetailsService
是一个接口,用来让spring-security知道从哪里获取数据库中的用户。由此,spring-security想要知道根据登录名和密码是否有该用户时,会调用UserDetailsService
的实现类,事实上之前用的构造于内存中的用户是spring-security对该接口的动态代理实现的。
所以,我们必须编写UserDetailsService
的实现类。
3. 使用数据库中的用户进行验证实现步骤
3.1 第一步:编写UserDetailsService
的实现类:UserDetailsServiceImpl
package cn.wanghao.springSecurity.service.impl;
import cn.wanghao.springSecurity.dao.UserDao;
import cn.wanghao.springSecurity.domain.SysRole;
import cn.wanghao.springSecurity.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
SysUser sysUser = userDao.selectByName(username);
List<SimpleGrantedAuthority> authorities = this.getAuthority(sysUser.getRoles());
User user = new User(sysUser.getUserName(), "{noop}" + sysUser.getPassWord(), authorities);
return user;
}
private List<SimpleGrantedAuthority> getAuthority(List<SysRole> roles) {
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
for (SysRole role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return authorities;
}
}
注意:上面的 sysUser.getPassWord() 前面加{noop}是因为密码没有加密,明文密码需要加这个。
3.2 第二部:更改spring-security配置文件
再在spring-security中去掉之前构造用户于内存中,该为从我们自定义的UserDetailsServiceImpl
类的对象中获取用户:
<!-- 在内存中构造用户们
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user" authorities="ROLE_USER"/>
<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>-->
<!-- 从数据库中获取用户 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userDetailsService">
</security:authentication-provider>
</security:authentication-manager>
3.3 效果
3.4 项目源码下载地址
链接:https://pan.baidu.com/s/1Xo1oVjVMvf_eM_9wHKZZqw |
---|
提取码:r211 |
数据库表如下:
sys_user表:
CREATE TABLE `sys_user` ( `id` int(32) NOT NULL AUTO_INCREMENT, `userName` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `passWord` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
sys_role表:
Create Table CREATE TABLE `sys_role` ( `id` int(32) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
sys_user_role表:
CREATE TABLE `sys_user_role` ( `user_id` int(32) NOT NULL, `role_id` int(32) NOT NULL, PRIMARY KEY (`user_id`,`role_id`), KEY `role_id` (`role_id`), CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`), CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84636.html