上一篇 <<<安全技术--接口幂等性设计
下一篇 >>>安全框架--JWT
Spring Security:一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。
Spring Security思想和Shiro一致,具体介绍参考:https://baike.baidu.com/item/spring%20security/8831652?fr=aladdin
2种实现方式
- a、Basic认证--基于HTTP协议的认证方式
.and().httpBasic()
- b、form表单模式
.and().formLogin()
应用场景
- 后台角色权限框架
- 授权认证oauth2.0
- 安全防护(防止跨站点请求)
- Session攻击
- 非常容易融合SpringMVC使用等
搭配RBAC权限模型核心代码
RBAC权限模型:基于角色的权限访问控制(Role-Based Access Control)
用户--角色--权限
- 账号及权限配置
// 配置认证用户信息和权限
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 查询数据库
auth.userDetailsService(myUserDetailsService).passwordEncoder(new PasswordEncoder() {
// 加密的密码与数据库密码进行比对CharSequence rawPassword 表单字段 encodedPassword
// 数据库加密字段
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
System.out.println("rawPassword:" + rawPassword + ",encodedPassword:" + encodedPassword+"---");
// 返回true 表示认证成功 返回fasle 认证失败
System.out.println(MD5Util.encode((String) rawPassword));
System.out.println(MD5Util.encode((String) rawPassword).equals(encodedPassword));
return MD5Util.encode((String) rawPassword).equals(encodedPassword);
}
// 对表单密码进行加密
@Override
public String encode(CharSequence rawPassword) {
return MD5Util.encode((String) rawPassword);
}
});
}
// 设置动态用户信息
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 1.根据用户名称查询数据用户信息
User user = userMapper.findByUsername(username);
if(null==user){
return null;
}
// 2.底层会根据数据库查询用户信息,判断密码是否正确交给框架内
// 3. 给用户设置权限
List<Permission> listPermission = userMapper.findPermissionByUsername(username);
System.out.println("username:" + username + ",对应权限:" + listPermission.toString());
//利用lanmda表达式将权限设置进去
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
listPermission.forEach(p -> {
authorities.add(new SimpleGrantedAuthority(p.getPermTag()));
});
user.setAuthorities(authorities);
return user;
}
}
- 所有权限配置
// 配置拦截请求资源
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry authorizeRequests = http
.authorizeRequests();
// 1.读取数据库权限列表
List<Permission> listPermission = permissionMapper.findAllPermission();
for (Permission permission : listPermission) {
// 设置权限
authorizeRequests.antMatchers(permission.getUrl()).hasAnyAuthority(permission.getPermTag());
}
/**
* 登录页面、登录成功或失败的跳转处理器,及关闭csrf模拟等
*/
authorizeRequests.antMatchers("/login").permitAll()
.antMatchers("/**").fullyAuthenticated()
.and().formLogin()
.loginPage("/login")
.successHandler(successHandler)
.failureHandler(failureHandler)
.and().csrf().disable();
}
- 重写错误页面配置
@Configuration
public class WebServerAutoConfiguration {
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
ErrorPage errorPage400 = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400");
ErrorPage errorPage401 = new ErrorPage(HttpStatus.UNAUTHORIZED, "/error/401");
ErrorPage errorPage403 = new ErrorPage(HttpStatus.FORBIDDEN, "/error/403");
ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
ErrorPage errorPage415 = new ErrorPage(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "/error/415");
ErrorPage errorPage500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
factory.addErrorPages(errorPage400, errorPage401, errorPage403, errorPage404, errorPage415, errorPage500);
return factory;
}
}
- 成功或失败后的跳转处理
// 认证成功
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse res, Authentication arg2)
throws IOException, ServletException {
System.out.println("用户认证成功");
res.sendRedirect("/");
}
}
//认证失败
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse res, AuthenticationException auth)
throws IOException, ServletException {
System.out.println("登陆失败!");
res.sendRedirect("/loginError");
}
}
关键源码图示
启动图示认证时序图
授权时序图
类图
相关文章链接:
<<<Web常用攻击手段-XSS攻击
<<<Web常用攻击手段-SQL注入
<<<Web常用攻击手段-Http请求防盗链
<<<Web常用攻击手段-CSRF攻击
<<<Web常用攻击手段-上传文件漏洞
<<<Web常用攻击手段-忘记密码
<<<Web常用攻击手段-其他漏洞
<<<安全技术--数据加密/认证技术
<<<安全技术--Https相关知识
<<<安全技术--接口幂等性设计
<<<安全框架--JWT
<<<安全框架--OAuth2
<<<安全架构整体设计方案
网友评论