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. 低副瓣阵列天线综合1 matlab HFSS

    车载雷达天线多采用微带贴片天线,贴片振子的形状多种多样,较常用的是矩形: 组阵时多采用先串馈再把串馈好的行或列单元采取并馈的方式组阵,无论是串馈或并馈,想要获得较低的副瓣效果,都需要采取电流幅度加权的 ...

  2. VMware显示错误:“未能锁定文件 无法打开磁盘 ..\*.vmdk 或者某一个快照所依赖的磁盘。”解决办法

    问题描述: 使用VMware时遇到错误:“未能锁定文件 无法打开磁盘 ..\*.vmdk 或者某一个快照所依赖的磁盘.” 问题出现的原因: 虚拟磁盘(.vmdk)本身有一个磁盘保护机制,为了防止多台虚 ...

  3. vue vuex开发中遇到的问题及解决小技巧

    1.在vue的开发中,如果使用了vuex,数据的组装,修改时在mutations中,页面是建议修改变量值的,如果强制修改,控制台就会出现错误.如下: 这种错误虽然不会影响结果,但是是vuex不提倡的方 ...

  4. 解析Json字符串中的指定的值

    { "head": { ", "Id": "20191008144448iAQE", "Message": & ...

  5. 《C# 爬虫 破境之道》:第一境 爬虫原理 — 第二节:WebRequest

    本节主要来介绍一下,在C#中制造爬虫,最为常见.常用.实用的基础类 ------ WebRequest.WebResponse. 先来看一个示例 [1.2.1]: using System; usin ...

  6. Nginx作为负载均衡服务器——server参数讲解

    upstream举例 upstream backend { server backend1.ecample.com weight = 5; # wwight 代表权重 server backend2. ...

  7. 2019CSP复赛游记

    Day 0 作为一个初三的小蒟蒻…… 什么算法都不会打…… 做一道LCA+生成树的图论题调了两个小时…… 明日裸考…… Day 1 Morning 买了两个士力架,带了一盒牛奶,准备在考场上食用(这个 ...

  8. sqlachemy查询对象转化成字典/json使用

    https://www.cnblogs.com/sanduzxcvbnm/p/10220718.html

  9. HCNA网络技术学习指南

    网络通信基础 网络与通信 OSI模型和TCP/IP模型 网络类型 传输介质及通信方式 2 VRP基础 VRP简介 VRP命令行 登录设备 基本配置 配置文件管理 通过Telnet登录设备 文件管理 基 ...

  10. AVR单片机教程——矩阵键盘

    本文隶属于AVR单片机教程系列.   开发板上有4个按键,我们可以把每一个按键连接到一个单片机引脚上,来实现按键状态的检测.但是常见的键盘有104键,是每一个键分别连接到一个引脚上的吗?我没有考证过, ...