1. maven依赖(在ssm依赖的基础上添加)
<properties>
<spring.security.version>5.0.2.RELEASE</spring.security.version>
</properties>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
2.配置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" xmlns:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="cn.msg.service.impl.UserServiceImpl"/>
<!-- 登录页面和错误页面不拦截-->
<security:http pattern="/login.jsp" security="none"></security:http>
<security:http pattern="/css/**" security="none"></security:http>
<security:http pattern="/img/**" security="none"></security:http>
<security:http pattern="/plugins/**" security="none"></security:http>
<!-- 配置拦截的规则
auto-config="使用自带的页面"
use-expressions="是否使用spel表达式",如果使用表达式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="true">
<!-- 配置拦截的请求地址,任何请求地址都必须有ROLE_USER或ROLE_ADMIN的权限当然这个是自己定义的-->
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
<!--
指定安全框架使用的页面若是不指定会使用security默认登入页面 此处指定了就要创建这些页面
login-page:指定登录页面
login-processing-url:登录的请求路径:登陆时必须使用的路径
default-target-url:登录成功后进入的页面
authentication-failure-url:认证失败后要进入的页面
-->
<security:form-login login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/login.jsp"
></security:form-login>
<!-- 关闭跨站请求伪造-->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
<!-- 配置认证信息:认证管理器-->
<security:authentication-manager>
<!-- 认证信息的提供者:关联用户服务对象,提供账号和密码 userService为UserDetailsService的实现类 -->
<security:authentication-provider user-service-ref="userService">
<!-- 用户的服务对象-->
<!-- <security:user-service> -->
<!--
用户信息:临时账号和密码
{noop}:不使用加密
authorities:指定用户的认证角色
-->
<!-- <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/> -->
<!-- </security:user-service> -->
<!--引用加密工具-->
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密工具类-->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- aop的自动代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--配置开启security的注解支持-->
<security:global-method-security secured-annotations="enabled"/>
</beans>
3.在web.xml中加载security.xml
在web.xml中编写
<!-- 加载spring.xml security.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml ,classpath:security.xml</param-value>
</context-param>
<!--配置委派代理过滤器: filter-name必须是:springSecurityFilterChain -->
<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.编写userService接口 此接口要继承UserDetailsService接口
public interface UserService extends UserDetailsService {
}
5.编写userService接口的实现类
因为userService接口继承了UserDetailsService接口所以UserServiceImpl也实现了UserDetailsService
@Transactional
public class UserServiceImpl implements UserService {
//usermapper我就不再编写演示了,只需直到他有一个方法login(String username)
//通过username获取用户信息,用户信息包含了用户所拥有的权限角色
@Autowired
private UserMapper userMapper;
//此为密码加密实用类在security.xml配置过了可向上翻看
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 登入
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1. 根据用户名查询一个 sysUser 对象
SysUser sysUser = userMapper.login(username);
if(sysUser!=null) {//若是对象存在
//授权集合
Collection<GrantedAuthority> authorities = new ArrayList<>();
//TODO 从sysUser中获取到 查询出来的 所有角色
for(SysRole role:sysUser.getRoleList()){
//此字符传拼接要与security.xml配置的权限名要对应
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+role.getRoleName());
authorities.add(authority);
}
//若是不需要权限配置可将上for循环注释然后解锁下面两行代码
// GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
// authorities.add(authority);
//参数1: 用户名 ; 参数2: 密码 (他们都来源于数据库)
//参数3: 授权集合
User user = new User(sysUser.getUsername(),sysUser.getPassword(), authorities);
return user;
}
return null;
}
}
6.前端防护
由上文可知此实例是有权限判断的可以根据不同用户所持有的权限角色展示不同的功能,security提供了<security:authorize access="hasRole('ROLE_ADMIN')">....</security:authorize>
标签可利用此标签对前端页面显示进行控制,上述标签的意思为:只有拥有‘ROLE_ADMIN’权限的用户登入时才会显示标签中的内容,使用标签前不要忘了声明<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
7.@Secured({""})注解 后台防护
防止没有权限的用户登入后使用地址栏进行恶意访问此用户没有的权限
使用方式