1.pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
</dependencies>
2.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"
username-parameter="username"
password-parameter="password"
login-processing-url="/login.do"
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>
3.web.xml
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-security.xml</param-value> </context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.IUserService
service必须继承UserDetailsService
public interface IUserService extends UserDetailsService {
public List<UserInfo> findAll()throws Exception;
}
5.IUserServiceImpl (SpringSecurity 代替了Controller控制层,在spring-security.xml配置了默认访问地址等)
Service实现类,**loadUserByUsername**是重写UserDetailsService的方法
@Service("userService")
@Transactional
public class IUserServiceImpl implements IUserService {
@Autowired
private IUserDao iUserDao;
@Override
//查询全部用户
public List<UserInfo> findAll() throws Exception {
return iUserDao.findAll();
}
@Override
//loadUserByUsername是重写UserDetailsService的方法
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = null;
try {
userInfo = iUserDao.findByUsername(username);
} catch (Exception e) {
e.printStackTrace();
}
//处理自己的用户对象封装成UserDetails,的实现类User
//User user=new User(userInfo.getUsername(),new BCryptPasswordEncoder().encode(userInfo.getPassword()),getAuthority(userInfo.getRoles())); --简单封装
//加入用户状态判断,userInfo.getStatus() == 1 ? true : false, true
User user = new User(userInfo.getUsername(), new BCryptPasswordEncoder().encode(userInfo.getPassword()),
userInfo.getStatus() == 1 ? true : false, true, true,
true, getAuthority(userInfo.getRoles()));
return user;
}
//用于获取用户状态
public List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> list = new ArrayList<>();
for (Role role : roles) {
SimpleGrantedAuthority simple = new SimpleGrantedAuthority("ROLE_" + role.getRoleName());
list.add(simple);
}
return list;
}
}
6.IUserDao
public interface IUserDao {
@Select("select * from users")
public List<UserInfo> findAll() throws Exception;
@Select("select * from users where username=#{username}")
//封装UserInfo实体类
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(column = "username", property = "username"),
@Result(column = "email", property = "email"),
@Result(column = "password", property = "password"),
@Result(column = "phoneNum", property = "phoneNum"),
@Result(column = "status", property = "status"),
//多对多的关系,封装
@Result(property = "roles", column = "id", javaType = List.class, many = @Many(select = "com.joyTop.dao.IRoleDao.findById"))
})
public UserInfo findByUsername(String username) throws Exception;
}
7.IRoleDao
IUserDao ,进行UserInfo封装时会调用权限数据,@Result(property = “roles”, column = “id”, javaType = List.class, many = @Many(select = “com.joyTop.dao.IRoleDao.findById”))
public interface IRoleDao {
//根据用户id,查询所有对应的角色
@Select("select * from role where id in(select roleId from users_role where userId =#{id})")
public List<Role> findById(String id)throws Exception;
}
8.退出
spring-security.xml中配置了《
<security:logout invalidate-session=“true” logout-url="/logout.do" logout-success-url="/login.jsp" /> 》logout.do,访问地址,并清楚session
<div class="pull-right">
<a href="${pageContext.request.contextPath}/logout.do"
class="btn btn-default btn-flat">注销</a>
</div>