文章目录
登陆功能
创建数据表
-- 用户表
CREATE TABLE users(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
email VARCHAR2(50) UNIQUE NOT NULL,
username VARCHAR2(50),
PASSWORD VARCHAR2(50),
phoneNum VARCHAR2(20),
STATUS INT
)
-- 角色表
CREATE TABLE role(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
roleName VARCHAR2(50) ,
roleDesc VARCHAR2(50)
)
-- 用户角色关联表
CREATE TABLE users_role(
userId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(userId,roleId),
FOREIGN KEY (userId) REFERENCES users(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
-- 资源权限表
CREATE TABLE permission(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
permissionName VARCHAR2(50) ,
url VARCHAR2(50)
)
-- 角色权限关联表
CREATE TABLE role_permission(
permissionId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(permissionId,roleId),
FOREIGN KEY (permissionId) REFERENCES permission(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
Role.角色类
public class Role {
private String id;
private String roleName;
private String roleDesc;
private List<Permission> permissions;
private List<UserInfo> users;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
public List<Permission> getPermissions() {
return permissions;
}
public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
}
public List<UserInfo> getUsers() {
return users;
}
public void setUsers(List<UserInfo> users) {
this.users = users;
}
@Override
public String toString() {
return "Role{" +
"id='" + id + '\'' +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
", permissions=" + permissions +
", users=" + users +
'}';
}
}
Permission.
public class Permission {
private String id;
private String permissionName;
private String url;
private List<Role> roles;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPermissionName() {
return permissionName;
}
public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Override
public String toString() {
return "Permission{" +
"id='" + id + '\'' +
", permissionName='" + permissionName + '\'' +
", url='" + url + '\'' +
", roles=" + roles +
'}';
}
}
配置spring-security.xml
1.添加failer.jsp和login.jsp到webapp下**
2.在resource下创建spring-security.xml**
3.配置加载类路径的配置文件添加spring-security.xml与applicationConfig.xml一同加载.
.
.
添加spring-security.xml内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不拦截的资源 -->
<security:http pattern="/login.jsp" security="none"/>
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/css/**" security="none"/>
<security:http pattern="/img/**" security="none"/>
<security:http pattern="/plugins/**" security="none"/>
<!--
配置具体的规则
auto-config="true" 不用自己编写登录的页面,框架提供默认登录页面
use-expressions="false" 是否使用SPEL表达式(没学习过)
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置具体的拦截的规则 pattern="请求路径的规则" access="访问系统的人,必须有ROLE_USER的角色" -->
<security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/>
<!-- 定义跳转的具体的页面 -->
<security:form-login
login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/failer.jsp"
authentication-success-forward-url="/pages/main.jsp"
/>
<!-- 关闭跨域请求 -->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" />
</security:http>
<!-- 切换成数据库中的用户名和密码 -->
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>-->
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密类 -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- 提供了入门的方式,在内存中存入用户名和密码
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
-->
</beans>
dao.
public interface IUserDao {
@Select("select * from users where username=#{username}")
public UserInfo findByUsername(String username) throws Exception;
}
Service.
public interface IUserService extends UserDetailsService {
}
ServiceImpl.
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao dao;
//解释了图片上的问题 Userdetails 与 用户对象的关系
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo =null;
try {
userInfo = dao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
//处理用户对象封装成UserDetails 然后传递给spring-security,进行认证
User user = new User(userInfo.getUsername(), userInfo.getPassword(), null);
return user;
}
}
Login.jsp.
登陆错误And解决.
输入正确用户名和密码一样错误.
插入数据:
insert into users values('111-222','[email protected]','tom','123','123',1);
因为我们spring-securit指出必须有必须有 ROLE_USER 或者 ROLE_ADMIN 角色
为User对象添加角色.
新错误.
解决.添加前缀
但是我们不应该自定义角色而是使用数据库中的角色信息.
使用中间表查询用户表和角色表的对应关系
IUserDao.
public interface IUserDao {
@Select("select * from users where username=#{username}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "email", column = "email"),
@Result(property = "password", column = "password"),
@Result(property = "phoneNum", column = "phoneNum"),
@Result(property = "status", column = "status"),
/*查询所有的角色封装到List集合里面*/
//多表查询
@Result(property = "roles",column = "id",javaType = java.util.List.class,many = @Many(select = "com.itheima.dao.IRoleDao.finRoleByUserId"))
})
public UserInfo findByUsername(String username) throws Exception;
}
IRoleDao.
public interface IRoleDao {
//根据用户的id查询对应的角色
//使用中间表进行进行查询
@Select("select * from role where id in (select roleId from users_role where userId=#{userId})")
public List<Role> finRoleByUserId(String userId) throws Exception;
}
向角色表中插入数据.
角色表:
insert into role values('1111','ADMIN','VIP');
中间表:
insert into users_role values('111-222','1111');
用户表:
insert into users values('111-222','[email protected]','tom','123','123',1);
debug查看是否有角色信息
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = null;
try {
userInfo = userDao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
//处理自己的用户对象封装成UserDetails
// User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(userInfo.getRoles()));
return user;
}
//作用就是返回一个List集合,集合中装入的是角色描述
public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> list = new ArrayList<>();
for (Role role : roles) {
list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
}
return list;
}
}
整理:
Role.实体类
@Data
public class Role {
private String id;
private String roleName;
private String roleDesc;
private List<Permission> permissions;
private List<UserInfo> users;
}
UserInfo.实体类
@Data
public class UserInfo {
private String id;
private String username;
private String email;
private String password;
private String phoneNum;
private int status;
private String statusStr;
private List<Role> roles;
}
Dao层:IUserDao 多表查询
public interface IUserDao {
@Select("select * from users where username=#{username}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "email", column = "email"),
@Result(property = "password", column = "password"),
@Result(property = "phoneNum", column = "phoneNum"),
@Result(property = "status", column = "status"),
@Result(property = "roles",column = "id",javaType = java.util.List.class,many = @Many(select = "com.itheima.dao.IRoleDao.findRoleByUserId"))
})
public UserInfo findByUsername(String username) throws Exception;
}
IRoleDao.对应IUserDao
public interface IRoleDao {
//根据用户id查询出所有对应的角色
@Select("select * from role where id in (select roleId from users_role where userId=#{userId})")
public List<Role> findRoleByUserId(String userId) throws Exception;
}
IUserService继承UserDetailsService
public interface IUserService extends UserDetailsService {
}
实现接口,间接继承UserDetailsService.重写方法
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = null;
try {
userInfo = userDao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
//处理自己的用户对象封装成UserDetails
// User user=new User(userInfo.getUsername(),"{noop}"+userInfo.getPassword(),getAuthority(userInfo.getRoles()));
User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(), userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(userInfo.getRoles()));
return user;
}
//作用就是返回一个List集合,集合中装入的是角色描述
public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> list = new ArrayList<>( );
for (Role role : roles) {
list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
}
return list;
}
}