Spring--Security-程序员宅基地

技术标签: spring  security  java  

在开发中经常会有需要在页面被访问时进行权限判断. 我们不可能在每个页面里进行各自的判断.显然应该将它做为一个切面来做.在WEB开发中可以使用过滤器.在过滤器里面集合进行判断.这样在判断逻辑变更时也能很快应对.在SSH的开发中可以手动写过滤器,也可以建Struts拦截器.还有一个功能较大的方案就是Spring的Security解决方案.
Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。
用户认证 一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。
用户授权 指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。
Spring验证方式有多种,可以将信息放在数据库中,然后在过滤器中定义数据库访问等信息,完成在数据库中取值进行比较.也可以自定义逻辑的比较.这里只说自定义逻辑的比较
下面是将Security 加到系统中的流程:
1.在 web.xml 中添加 Spring Security 的过滤器.在 web.xml 中加入如下代码:
  <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>

public class CustomSecurityFilter extends AbstractPreAuthenticatedProcessingFilter {
   
@Override
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
if (logger.isDebugEnabled()) {
logger.debug("检查权限: "
+ SecurityContextHolder.getContext().getAuthentication());
}
SecurityContextHolder.getContext().setAuthentication(null);
super.doFilterHttp(request, response, filterChain);
}

// 一个实现了UserDetails接口的对象(权限主体)
private AuthenticationUserDetailsService authenticationUserDetailsService;
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
// 从SESSION中取用户权限
HttpSession nowSession = request.getSession(false);
UserInfoDto userInfo = null;

List<UserRightDto> rightList = new ArrayList<UserRightDto>();
UserRightDto noAccess = new UserRightDto();
noAccess.setId(SystemConst.ROLE_NOACCESS);

if (null == nowSession) {
return rightList;
}
userInfo = (UserInfoDto) nowSession.getAttribute(SystemConst.LOGIN_USER_INFO);
if (null == userInfo) {
return rightList;
}
if (userInfo.getRightList() == null || userInfo.getRightList().size() <= 0) {
return rightList;
}
return userInfo.getRightList();
}
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
return authenticationUserDetailsService;
}
@Override
public int getOrder() {
// AbstractPreAuthenticatedProcessingFilter类上进行扩展返回预验证过滤器位置
return FilterChainOrder.PRE_AUTH_FILTER;
}

// -------------以下是getter setter方法-------------//

public AuthenticationUserDetailsService getAuthenticationUserDetailsService() {
return authenticationUserDetailsService;
}
public void setAuthenticationUserDetailsService(
AuthenticationUserDetailsService authenticationUserDetailsService) {
this.authenticationUserDetailsService = authenticationUserDetailsService;
}
}

CustomSecurityuserInfoService.java
package cn.panasonic.common.interceptor.security;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException;

import cn.panasonic.common.dto.UserRightDto;
import cn.panasonic.common.utility.SystemConst;

public class CustomSecurityuserInfoService implements AuthenticationUserDetailsService {
// 用户集保存Map
private Map<String, BaseUserDetails> userMap = null;
@SuppressWarnings("unchecked")
@Override
public UserDetails loadUserDetails(Authentication token)
throws UsernameNotFoundException {
// 当前访问者的权限列表
List<UserRightDto> rightList = (List<UserRightDto>) token.getCredentials();
if (rightList == null || rightList.size() <= 0) {
return new BaseUserDetails(SystemConst.ROLE_NOACCESS,
SystemConst.ROLE_NOACCESS,
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_NOACCESS") });
}
GrantedAuthority[] rightArr = new GrantedAuthority[rightList.size()];
// 根据当前访问者的权限列表返回它在Spring中的权限.
for (int i = 0; i < rightList.size(); i++) {
rightArr[i] = userMap.get(rightList.get(i).getId()).getAuthorities()[0];
}

BaseUserDetails user = new BaseUserDetails("username", "password", rightArr);

return user;
}
public CustomSecurityuserInfoService() {
userMap = new HashMap<String, BaseUserDetails>();
// 都无法访问
BaseUserDetails userInfo = null;
userInfo = new BaseUserDetails(SystemConst.ROLE_NOACCESS,
SystemConst.ROLE_NOACCESS,
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_NOACCESS") });
userMap.put(SystemConst.ROLE_NOACCESS, userInfo);
// 管理员权限
userInfo = null;
userInfo = new BaseUserDetails(SystemConst.ROLE_ADMIN, SystemConst.ROLE_ADMIN,
new GrantedAuthority[] { new GrantedAuthorityImpl("ROLE_ADMIN") });
userMap.put(SystemConst.ROLE_ADMIN, userInfo);
}
}

配置已经完成.将项目发布到WEB容器中.启动容器时,CustomSecurityuserInfoService.java 会先被初始化,所以它的构造函数会被执行,就是上面的初始化所有权限.
在我们访问项目的页面时,如上面已经配置的:user0101Actin.do.这时候CustomSecurityFilter.java的doFilterHttp被执行.过滤开始.然后就是getPreAuthenticatedCredentials方法.这时候用户所有的认证信息会被返回.最后执行的就是CustomSecurityuserInfoService.java的loadUserDetails方法.这就是关键.上面步骤返回的是它在系统中的权限.而这里要返回的是该用户在Spring Security上下文中的认证信息.记得上面配置URL时在后面的access后会有ROLE_ADMIN,ROLE_NROMAL这样的配置.Spring Security会在这里返回的用户认证信息的权限列表中查看,是否包含access列表中的某一个,如果包含任意一个,就表示是有访问权限.
简单来说,要想访问通过,就要在loadUserDetails返回的用户信息的权限列表:GrantedAuthority[]中包括URL后设置可访问权限字符串中的一个.
原文地址:[url]http://blog.sina.com.cn/s/blog_5f54f0be0100u7wd.html[/url]
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lizaochengwen/article/details/84133463

智能推荐

基于Springboot + vue实现的交通管理在线服务系统-程序员宅基地

文章浏览阅读271次,点赞4次,收藏4次。管理员管理:负责添加、删除、修改管理员账号,并设置相应的权限,确保管理员团队的专业性和高效性。新闻信息管理:发布、编辑和删除交通新闻、政策更新、路况信息等,保持信息的实时性和有效性。驾驶证业务管理:在线提交驾驶证申请、查询、更新、补办等业务,并实时查看办理进度。新闻信息查看:浏览系统发布的交通新闻、政策更新、路况信息等,了解最新的交通动态。机动车业务管理:在线提交车辆注册、年检、转移、报废等业务申请,并获取办理结果。用户管理:管理用户账号,包括用户注册、登录、权限设置等,确保系统的安全性。

打印系统开发(42)——静默打印_静默打印是什么意思-程序员宅基地

文章浏览阅读4.4k次。1.问题描述希望每次打印时,都是用固定的打印机打印并且不希望弹出对话框进行设置,此时便可以设置静默打印。1.1什么是静默打印静默打印即点击打印时不弹出选项窗口和打印机设置窗口直接进行打印。1.2支持静默打印的打印方式零客户端打印、本地打印、服务器端打印支持静默打印。2.静默打印设置方法2.1 零客户端打印设置方法注:只支持 IE点击模板-打印..._静默打印是什么意思

STM32+74HC595:带领你10分钟用对74HC595_74hc595连接stm32-程序员宅基地

文章浏览阅读2.4w次,点赞14次,收藏68次。使用的是STM32CBT8,小模块用起来性价比超级高,资源丰富,移植u/COS及HTTP、MQTT协议等等用起来简直欲罢不能,摇摇欲仙!BUT:IO口资源太少了,我想让你驱动100个LED,你缺告诉我,我的要求太多,你满足不了......还好,找到了74HC595,但是网上很多资源讲的我看了半天才总结、提炼并另辟蹊径出来精髓===============================_74hc595连接stm32

莱昂哈德·欧拉生平及其成就简介_欧拉的物理成就-程序员宅基地

文章浏览阅读4.1k次,点赞2次,收藏8次。莱昂哈德·欧拉(Leonhard Euler ,1707年4月15日~1783年9月18日),瑞士数学家、自然科学家。1707年4月15日出生于瑞士的巴塞尔,1783年9月18日于俄国圣彼得堡去世。欧拉出生于牧师家庭,自幼受父亲的影响。13岁时入读巴塞尔大学,15岁大学毕业,16岁获得硕士学位。欧拉是18世纪数学界最杰出的人物之一,他不但为数学界作出贡献,更把整个数学推至物理的领域。他是数学史上最多产的数学家,平均每年写出八百多页的论文,还写了大量的力学、分析学、几何学、变分法等的课本,《无穷小分析引论》、_欧拉的物理成就

Error: PL/SQL: ORA-00980: 同义词转换不再有效_sql数据库中同义词转换不再有效-程序员宅基地

文章浏览阅读1.5w次。今天在写存储过程的时候,碰到一个问题,在执行存储过程的时候总是报错--同义词转换不再有效,发现一个查询语句中的一个表原来使用的是一个同义词,就试着把这个同义词单独拿出来进行查询操作,发现并没有问题。最后,经过一番努力,发现该同义词并不是直接指向一个实体表,而是指向另一个同义词。所以,将改同义词的指向改为直接指向原实体表的指向,问题得到解决。即同义词指向的 object ow_sql数据库中同义词转换不再有效

idea 怎么修改项目名字和modules配名字_idea修改groupid-程序员宅基地

文章浏览阅读2.5k次。我们会遇到很多场景比如说git拉取一个项目改成自己的 或者架构师搭建架构喊你拿过来用 是不是的改名字。mvn idea:module 这个是生成.iml文件 删除以前的.iml.重新导入工程编辑运行。第五 补充 如果发现你改项目能把原来的项目modules也改了。第二步 改 点击project Stucture。a/是项目名字 name 也是。第三步 改modules。_idea修改groupid

随便推点

深刻对比一下阿里云服务器和腾讯云服务器的优劣和区别_腾讯云与阿里云的优劣-程序员宅基地

文章浏览阅读2.5w次,点赞10次,收藏19次。我来简单对比阿里云服务器和腾讯云服务器的优劣和区别腾讯云相比阿里云优势不明显。阿里云比腾讯云开放的时间更早,辅助系统更完善些,功能更多可用性更强。但腾讯云不是单纯卖云服务的,凡是要接入腾讯的生态(比如微信小程序等)必须得用腾讯云服务器,腾讯云迅速发展壮大。腾讯云也在慢慢完善,大多数应用场景也都能满足,但就是对很多新技术的支持总是比阿里云慢一些,高级的配置定制也少一些。服务器结构不是很复杂的话用......_腾讯云与阿里云的优劣

应用C预处理命令_c 添加预处理命令-程序员宅基地

文章浏览阅读1.6k次。********************************LoongEmbedded******************************** 作者:LoongEmbedded(kandi)时间:2011.10.17类别:C基础************_c 添加预处理命令

Acrobat 版本校验异常,请检查网络连接是否正常:NotAllowedError;安全性设置禁止访问本属性或方法。_版本校验异常,请检查您的电脑网络连接是否正常-程序员宅基地

文章浏览阅读1.3w次。一、上传企业所得税纳税申报表时,Acrobat提示版本校验异常,请检查您的电脑网络连接是否正常:NotAllowedError;安全性设置禁止访问本属性或方法。二、解决方法打开Acrobat DC 阅读器的然后 在菜单栏 --找到编辑--再选择首选项,添加该文件(如图)或者添加文件夹路径(注意:添加文件夹下面的路径将全部都会有权限,如果不是非必要,可以直接添加文件。)完_版本校验异常,请检查您的电脑网络连接是否正常

贪心算法——C++实现中级案例_c++贪心算法代码-程序员宅基地

文章浏览阅读95次。在贪心算法中,我们每次都选择当前状态下最优决策,然后更新状态,直到达到最终状态。本文将介绍几个经典的贪心算法案例,并给出C++代码实现。有n个任务需要调度,每个任务需要占用一个时间单位,并且有一个冷却期k。贪心算法本身也是一个很好的思维训练工具,可以帮助我们更好地理解问题本质和设计高效的算法。给定一个按升序排列的整数数组,将其划分成多个长度至少为3的连续子序列,每个子序列只包含连续的整数。有m个孩子和n个糖果,每个孩子有对应的贪婪值g_i和每个糖果有对应的大小s_i。贪心算法——C++实现中级案例。_c++贪心算法代码

从jeecg开源代码看泛型类型擦除之妙用_((dict)field.getannotation(dict.class)).dicttable(-程序员宅基地

文章浏览阅读446次,点赞10次,收藏14次。看代码与输出可以看出类型已被擦除,泛型不匹配或不指定只会产生编译告警,并不会产生编译错误,更不会运行错误。_((dict)field.getannotation(dict.class)).dicttable()

Python+GDAL进行影像坐标转换_python gdal transformpoint-程序员宅基地

文章浏览阅读1.1k次。Python实现遥感影像坐标转换_python gdal transformpoint

推荐文章

热门文章

相关标签