springSecurity 可以解决两个问题
认证:可以看做登录
权限:可以看做操作功能
自定义认证 在浏览页面时 去session中查看是否有信息 如果有 说明登录,没有说明没有登录(跳转登录页面) filter 过滤器 intercepter 拦截器
springSecurity 是由11中filter 组成的过滤器链
使用步骤
1.权限框架的入门示例
1.新建web工程
2.工程引入框架使用的依赖
3.web.xml文件配置权限框架过滤器
<!--配置监听器记载权限框架配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springSecurity.xml</param-value>
</context-param>
<!--配置框架使用的filter过滤器-->
<filter>
<!--过滤器执行链名臣固定springSecurityFilterChain-->
<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.配置框架使用的配置文件 security.xml 配置拦截的规则和放行的条件
<!--配置拦截器的路径规则
auto-config="true" 表示使用权限框架默认的配置
use-expressions="false" 关闭权限框架的表达式 spel
intercept-url 拦截请求资源的路径
access="ROLE_USER" 允许访问的条件 当前用户必须拥有ROLE_USER的角色才可以访问
-->
<security:http auto-config="true" use-expressions="false">
<security:intercept-url pattern="/**" access="ROLE_USER"></security:intercept-url>
</security:http>
<!--配置拦截后验证的节点-->
<security:authentication-manager>
<security:authentication-provider>
<!--测试使用框架提供的默认user业务类验证权限-->
<security:user-service>
<!--自定义测试的用户名密码
用户amdin 密码为 admin 默认拥有权限为ROLE_ADMIN
用户user 密码为 user 默认拥有权限为ROLE_USER
{noop} 表示明文密码验证 密文密码为加密后的密码字符串
123456=fxf434dfaljfd244sdfd
-->
<security:user name="admin" password="{noop}admin" authorities="ROLE_ADMIN"> </security:user>
<security:user name="user" password="{noop}user" authorities="ROLE_USER"></security:user>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
2.自定义页面的实现
1.添加form登录处理节点
<!--自定义页面的配置节点-->
<security:form-login login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/error.jsp"></security:form-login>
2.处理无权限的页面跳转
<!--登录成功权限不足的处理-->
<security:access-denied-handler error-page="/403.jsp"></security:access-denied-handler>
3.关闭跨域的请求拦截
<!--csrf关闭跨域请求的攻击-->
<security:csrf disabled="true"></security:csrf>
4.添加自定义的 login.jsp error.jsp 403.jsp
3.引入权限框架到ssm案例项目中
1.web.xml配置过滤器执行链
2.security的配置文件被web文件加载
3.用的自定义页面引入的webapp下
4.使用真实的数据库用户验证权限的登录
1.初始化user表结构
CREATE TABLE sys_user(
id NUMBER PRIMARY KEY ,
username VARCHAR2(50),
email VARCHAR2(50) ,
PASSWORD VARCHAR2(80),
phoneNum VARCHAR2(20),
STATUS NUMBER(1)
);
2.配置文件修改验证使用自定义id业务类
<security:authentication-provider user-service-ref="userService">
<!--读取数据库的真实用户验证账号密码是否正确
配置自定义的userServcie实现类被框架使用判断
规则为:userService 必须继承框架的接口UserDetailsService
目的是复写方法 loadUserByName 通过用户名查询数据库的用户
-->
</security:authentication-provider>
3.自定义userService继承框架接口 实现方法
@Service("userService")
public class SysUserServiceImpl implements SysUserService {
@Autowired
private SysUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//得到数据库的用户
SysUser sysUser = userDao.findUserByName(username);
//框架的User对象用于验证返回 用户名 密码 用户的权限集合
//测试创建权限集合赋予权限为ROLE_USER
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
//赋予用户固定权限为ROLE_USER
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
User user = new User(sysUser.getUsername(),"{noop}"+sysUser.getPassword(),authorities);
return user;
}
}
用户注册时给用户密码是加密
在springSecurity.xml中添加盐值
<!--通过配置文件方式初始化加密的工具类-->
<bean id="pwdEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
代码中
@Autowired
BCryptPasswordEncoder pwdEncoder;
@Override
public void saveUser(SysUser user) {
//获取user对象中原始的密码
String pwd = user.getPassword();
user.setPassword(pwdEncoder.encode(pwd));
userDao.saveUser(user);
}
解密代码
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//得到数据库的用户
SysUser sysUser = userDao.findUserByName(username);
//框架的User对象用于验证返回 用户名 密码 用户的权限集合
//查询得到用户真正的角色集合返回
List<Role> roles =sysUser.getRoles();
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
///如果当前用户确实拥有角色 循环添加到集合中
if(roles!=null&&roles.size()>0){
for (Role role : roles) {
authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
}
}
User user = new User(sysUser.getUsername(),sysUser.getPassword(),authorities);
return user;
}