SpringSecurity

  SpringSecurity融合Spring技术栈,提供JavaEE应用的整体安全解决方案;提供全面的安全服务。Spring Security支持广泛的认证模型

模块划分

Core - spring-security-core.jar

核心模块:核心认证、授权功能、支持jdbc-user功能、支持独立的Spring应用

Remoting - spring-security-remoting.jar

远程交互模块:一般不需要,可以使用Spring Remoting功能简化远程客户端交互

Web - spring-security-web.jar

web安全模块:web项目使用,基于URL的访问控制(access-control)

Config - spring-security-config.jar

java配置模块:必须依赖包,包含解析xml方式和java 注解方式来使用SpringSecurity功能

LDAP - spring-security-ldap.jar

ldap(轻量目录访问协议)支持模块:可选依赖包,LDAP功能支持

ACL - spring-security-acl.jar

ACL支持:ACL(Access-Control-List)访问控制列表。细粒度的资源访问控制(RBAC+ACL)

CAS - spring-security-cas.jar

CAS整合支持:CAS(Central Authentication Service)中央认证服务。开源ApereoCAS整合

OpenID - spring-security-openid.jar

OpenID 认证方式: 用于针对外部服务器对用户进行身份验证(微信,新浪微博第三方登录)

Test - spring-security-test.jar

测试模块:快速的测试SpringSecurity应用

基于Maven Web工程实例

  添加 security-pom 依赖

    <!-- 安全框架中的jar包 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>
<!-- 标签库 -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>4.2.10.RELEASE</version>
</dependency>

  web.xml 中添加 SpringSecurity的 Filter 进行安全控制

  <!-- 核心控制器,注意需将spring及springmvc配置文件都由Web容器装载 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/spring/springmvc.xml
classpath*:/spring/spring-*.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--代理管理所有 SpringSecurity 过滤器-->
<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>

  SpringSecurity 配置类

/**
* @Configuration 管理程序中的组件(扫描)
* @EnableWebSecurity 安全框架支持注解的形式 基础注解
* @EnableGlobalMethodSecurity 开启使用表达式方法验证安全性
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override //认证
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
}
@Override //授权
protected void configure(HttpSecurity http) throws Exception {
}
}

  查看登录页面的源码,有个标签<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 这是SpringSecurity 帮我们防止“跨站请求伪造”攻击;还可以防止表单重复提交。此标签 value 值会动态生成一个令牌值当用户请求登录时会验证此令牌值的正确性。如果想禁用此功能可在配置类中设置 http.csrf().disable();

l  令牌值变化:

如果登录成功(用户名,密码正确),令牌会被删除,

重新回到登录页或后退网页,令牌会重新生成;

如果登录失败(用户名,密码错误),令牌不变。

刷新登录页,令牌值也不变

认证

    @Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//从数据库中查询数据
  auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}

UserDetailsService

  此接口由 Security 来调用基于 AOP 模式进行权限检查,返回一个 UserDetails 接口类型其存放着该用户从数据库查询出来的所有权限信息

步骤:
  1 在业务层实现 UserDetailsService 接口通过用户名从 Dao 层查询出该用户对象
  2 创建一个 HashSet<GrantedAuthority> 接口类型的集合,该 GrantedAuthority 类型用来存放角色和权限信息,它的实现类 SimpleGrantedAuthority 需要传入字符串类型角色名和权限名
  3 通过该用户 id 查询出该用户所拥有的角色集合
  4 通过该用户 id 查询出该用户所拥有的权限集合
  5 通过所有角色名和所有权限名 创建 SimpleGrantedAuthority 对象并添加到 HashSet<GrantedAuthority> 集合中
  6 创建 User 类对象,该对象实现了 UserDetails 接口,为此 user 对象传入该用户的用户名和密码加上权限集合 Set 并返回该对象即可
    @Autowired //用户
private TAdminMapper adminMapper;
@Autowired //角色
private TRoleMapper roleMapper;
@Autowired //权限
private TPermissionMapper permissionMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
TAdminExample example = new TAdminExample();
TAdminExample.Criteria criteria = example.createCriteria();
criteria.andLoginacctEqualTo(username);
List<TAdmin> admins = adminMapper.selectByExample(example);
//从数据库中查出该用户
TAdmin admin = admins.get(0);
//该集合用来存放角色和权限
HashSet<GrantedAuthority> authorities = new HashSet<>();
//从数据库中查出该用户所对应的角色
List<TRole> roles = roleMapper.listRole(admin.getId());
//从数据库中查出该用户所对应的权限
List<TPermission> permissions = permissionMapper.listPermission(admin.getId());
//分别将角色和权限添加到 authorities 集合中
for (TRole role : roles) {
String name = role.getName();
authorities.add(new SimpleGrantedAuthority("ROLE_" + name));//注意角色需加上 "ROLE_"
}
permissions.forEach((p) -> {
String name = p.getName();
authorities.add(new SimpleGrantedAuthority(name));
});
//通过该用户名和密码以及权限集合创建User对象并返回
User user = new User(admin.getLoginacct().toString(), admin.getUserpswd().toString(), authorities);
return user;
}

授权

HttpSecurity 该类允许对特定的http请求基于安全考虑进行配置。默认情况下,适用于所有的请求.亦通过该对象 http 方法为用户配置精细化权限访问控制

    @Override
protected void configure(HttpSecurity http) throws Exception {
//基于httpRequest对指定antMatchers资源permitAll放行,对于其他请求anyRequest必须通过认证authenticated
http.authorizeRequests().antMatchers("/welcome.jsp","/static/**")
.permitAll().anyRequest().authenticated();
//跳转到默认登录界面
http.formLogin().loginPage("/welcome.jsp");
//登录时指定的控制器/login,并验证用户名和密码,成功验证后跳转到控制器/main
http.formLogin().loginProcessingUrl("/login")
.usernameParameter("loginacct")
.passwordParameter("userpswd")
.defaultSuccessUrl("/main");
//取消csrf令牌值验证
http.csrf().disable();
//退出时指定的控制器,并指定成功退出后登录界面
http.logout().logoutUrl("/exit").logoutSuccessUrl("/welcome.jsp");
//记住我功能.需在前端复选框中指定 value 值为 remember-me
http.rememberMe();
//自定义的异常处理器
http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
//判断是否为异步请求
if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))){
response.getWriter().write("403");
}else {
request.setAttribute("msg",accessDeniedException.getMessage());
request.getRequestDispatcher("/WEB-INF/views/unauth.jsp")
.forward(request,response);
}
}
});
}

  通过方法调用可以更精细化控制访问权限   

    authorizeRequests():返回一个配置对象用于配置请求的访问限制
    formLogin():返回表单配置对象,当什么都不指定时会提供一个默认的,如配置登录请求,还有登录成功页面
    logout():返回登出配置对象,可通过logoutUrl设置退出url
    antMatchers:匹配请求路径或请求动作类型,如:.antMatchers("/admin/**")
    addFilterBefore: 在某过滤器之前添加 filter
    addFilterAfter:在某过滤器之后添加 filter
    addFilterAt:在某过滤器相同位置添加 filter,不会覆盖相同位置的 filter
    hasRole:结合 antMatchers 一起使用,设置请求允许访问的角色权限或IP

方法名

用途

access(String)

SpringEL表达式结果为true时可访问

anonymous()

匿名可访问

denyAll()

用户不可以访问

fullyAuthenticated()

用户完全认证访问(非remember me下自动登录)

hasAnyAuthority(String…)

参数中任意权限可访问

hasAnyRole(String…)

参数中任意角色可访问

hasAuthority(String)

某一权限的用户可访问

hasRole(String)

某一角色的用户可访问

permitAll()

所有用户可访问

rememberMe()

允许通过remember me登录的用户访问

authenticated()

用户登录后可访问

hasIpAddress(String)

用户来自参数中的IP可访问

@EnableGlobalMethodSecurity详解

    @EnableGlobalMethodSecurity(securedEnabled=true) 开启@Secured 注解过滤权限

      @Secured("软件工程师") :拥有指定角色才可以访问方法

    @EnableGlobalMethodSecurity(jsr250Enabled=true)开启@RolesAllowed 注解过滤权限

    @EnableGlobalMethodSecurity(prePostEnabled=true) 使用 SpEL 表达式方法级别的安全性         4个注解可用

@PreAuthorize 在方法执行之前检查,基于表达式的计算结果来限制对方法的访问   //@PreAuthorize("hasRole('软件工程师')")

@PostAuthorize 在方法执行后检查,但是如果表达式计算结果为false,将抛出一个安全性异常

@PostFilter 允许方法调用,但必须按照表达式来过滤方法的结果

@PreFilter 允许方法调用,但必须在进入方法之前过滤输入值

Security 标签

  在 jsp 页面还可通过标签进一步控制 html 标签的访问权限或获取该用户信息 : 引入标签库

<%@taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
 <sec:authentication property="name"/> //在需要位置显示用户登录名, 属性 property 必须是 name
<sec:authorize access="hasRole('PM - 项目经理')">//非此角色用户隐藏下面的标签
<button type="button" id="deleteBath" class="btn btn-danger" style="float:right;margin-left:10px;">删除</button>
</sec:authorize>

Java框架之SpringSecurity-权限系统的更多相关文章

  1. python的Web框架,auth权限系统

    使用django默认权限系统实现用户登录退出 判断用户是否登录 request.user.is_authenticated 返回的为bool值 一个简单的登录视图范式: # 导包 from djang ...

  2. 基于SpringBoot+SpringSecurity+mybatis+layui实现的一款权限系统

    这是一款适合初学者学习权限以及springBoot开发,mybatis综合操作的后台权限管理系统 其中设计到的数据查询有一对一,一对多,多对多,联合分步查询,充分利用mybatis的强大实现各种操作, ...

  3. SpringSecurity权限管理系统实战—六、SpringSecurity整合jwt

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

  4. 常见JAVA框架

     Spring Framework [Java开源JEE框架] Spring是一个解决了许多在J2EE开发中常见的问题的强大框架. Spring提供了管理业务对象的一致方法并且鼓励了注入对接口编程而不 ...

  5. S2SH商用后台权限系统第一讲

    各位博友: 您好!从今天开始我们做一套商用的权限系统.功能包含用户管理.角色管理.模块管理.权限管理.大家知道每个商用系统肯定会拥有一套后台系统,我们所讲的权限系统是整个系统核心部分.本套系统技术有s ...

  6. 高校手机签到系统——第一部分Authority权限系统(上)

    序:今天开始写一个算是我第一个系列的文章——高校手机签到系统.本系统结合我们学校自身的一些特点编写.这是我的毕业设计项目,写在这里算是给最后论文的时候一些点滴的记录.另外也想通过这个系列的文章找到一份 ...

  7. Spring Security和 JWT两大利器来打造一个简易的权限系统。

    写在前面 关于 Spring Security Web系统的认证和权限模块也算是一个系统的基础设施了,几乎任何的互联网服务都会涉及到这方面的要求.在Java EE领域,成熟的安全框架解决方案一般有 A ...

  8. Shiro整合springboot,freemaker,redis(含权限系统完整源码)

    区块链技术联盟 2018-02-08 17:06:40 目录 一.导语 二.shiro功能介绍 三.shiro详解 四.shiro实战案例分享 五.系统配置 六.其他 一.导语 今天推荐给大家一个非常 ...

  9. 转 分享我在阿里工作十年接触过Java框架设计模式

    转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...

随机推荐

  1. JS获取时间戳的几种方法与区别

    var today = new Date() Date.now()) Date.parse(today) today.valueOf()) today.getTime() 可以看出,第二种是精确到秒的 ...

  2. css控制div等比高度

    在移动端开发中,在banner轮播图未加载出来之前,banner层是不占文档流高度的,当从服务器获取完banner数据,展示的时候,banner层因为有了内容 所以会撑开,导致banner层下面的内容 ...

  3. 常用Java静态代码分析工具的分析与比较

    给国产静态代码检测工具Pinpoint打Call! 简介 本文首先介绍了静态代码分析的基本概念及主要技术,随后分别介绍了4种现有的主流Java静态代码分析工具 (Checkstyle,FindBugs ...

  4. pandas操作mysql从放弃到入门

    目录 相关帮助文档 一.如何读取数据库-read_sql 二.如何筛选数据 三.如何连表-merge 四.如何删除一行或一列-drop 五.如何分组统计-groupyby 六.如何排序-sort_va ...

  5. cogs 3. 服务点设置 dijkstra

    3. 服务点设置 ★   输入文件:djsa.in   输出文件:djsa.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 为了进一步普及九年义务教育,政府要在某乡镇建 ...

  6. 四、JVM之栈与栈帧

    栈: 1.又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把 另一端称为栈底.其特性是先进后出. 2.栈是线程私有的,生命周期跟线程相同,当创 ...

  7. win10关闭系统更新 (转载)

    一.关闭Windows10系统的自动更新服务 1:使用快捷键Win+R,打开运行 2:输入命令:services.msc,打开系统服务界面 找到Windows Update双击 将启动类型改为[禁用] ...

  8. Java单体应用 - 架构模式 - 01.三层架构

    原文地址:http://www.work100.net/training/monolithic-architecture-3level.html 更多教程:光束云 - 免费课程 三层架构 序号 文内章 ...

  9. mybatis in查询

    原文地址:https://blog.csdn.net/u012427355/article/details/79580561 foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集 ...

  10. 1、python3.x安装(windows)

    现在大部分自动化测试已经使用python3.x版本,与Python2的区别这里就不多说了,如有兴趣可以自行百度. 一.下载 官网:https://www.python.org/downloads/,下 ...