Spring Security 整合freemaker 实现简单登录和角色控制
Spring Security 整合freemaker 实现简单登录和角色控制
写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制。整个过程很简单,在此给大家梳理一下,也算是自己对知识点的一个总结。
一、需求分析:
我们都知道,电商网站在权限这一块,有两大块内容:
1、用户未登录,部分页面拒绝访问(如:下订单)
2、不同角色用户登录看到的功能模块不一样(如:买家、卖家、客服等)
基于以上需求,接下来我们要解决的就是对用户登录的拦截以及对权限和角色的控制。
二、项目环境说明:
使用SSM(SpringMVC+Spring+Mybatis)框架,mysql数据库、maven项目管理工具,freemaker前端引擎。对以上又不懂的朋友们可以自己去百度了解,这里就废话不多说了。
三、前期储备知识(如果对Spring Security很熟悉的可以跳过此步)
Security框架可以精确控制页面的一个按钮、链接,它在页面上权限的控制实际上是通过它提供的标签来做到的。
简介
一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方式的安全框架(简单说是对访问权限进行控制嘛),应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。spring security的主要核心功能为认证和授权,所有的架构(如:Shiro安全框架)也是基于这两个核心功能去实现的。
框架原理
众所周知 想要对对Web资源进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。所以springSecurity在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全。
如下为其主要过滤器 :
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
UsernamePasswordAuthenticationFilter
BasicAuthenticationFilter
框架的核心组件
SecurityContextHolder:提供对SecurityContext的访问
SecurityContext,:持有Authentication对象和其他可能需要的信息
AuthenticationManager 其中可以包含多个AuthenticationProvider
ProviderManager对象为AuthenticationManager接口的实现类
AuthenticationProvider 主要用来进行认证操作的类 调用其中的authenticate()方法去进行认证操作
Authentication:Spring Security方式的认证主体
GrantedAuthority:对认证主题的应用层面的授权,含当前用户的权限信息,通常使用角色表示
UserDetails:构建Authentication对象必须的信息,可以自定义,可能需要访问DB得到
UserDetailsService:通过username构建UserDetails对象,通过loadUserByUsername根据userName获取UserDetail对象
以上知识点来源于博客:springSecurity安全框架的学习和原理解读
四、开始实战:
本文内容主要实现三部分内容:
1、控制不同角色只能访问网站中不同链接(与2作区分)
2、控制不同角色用户看到网站中不同的模块
3、对有权限控制的路径,控制用户session过期时重新跳转到登录页面
- 在pom.xml文件中加入Security 坐标:
- <!--spring security 依赖包-->
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-core</artifactId>
- <version>3.2.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-web</artifactId>
- <version>3.2.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-config</artifactId>
- <version>3.2.0.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-taglibs</artifactId>
- <version>3.2.0.RELEASE</version>
- </dependency>
- 在web.xml中配置Security
- <!--配置Spring Security-->
- <!--filter的声明-->
- <filter>
- <filter-name>springSecurityFilterChain</filter-name>
- <filter-class>
- org.springframework.web.filter.DelegatingFilterProxy
- </filter-class>
- </filter>
- <!--mapping就是filter的映射,就是哪些文件用到这个filter-->
- <filter-mapping>
- <filter-name>springSecurityFilterChain</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- Controller文件代码 (SecurityConfig.java)
- @Configuration
- @EnableWebSecurity
- @Component
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired
- private UserDetailService userDetailService;
- @Override
- protected void configure(HttpSecurity http) throws Exception{
- http.authorizeRequests()
- .antMatchers("/index/show").hasAnyRole("ADMIN","BUYER","SELLER")//个人首页只允许拥有ADMIN,BUYER,SELLER角色的用户访问
- .antMatchers("/cart/show").hasAnyRole("ADMIN","MAIJIA","SELLER")
- //在此后面可以根据自己的项目需要进行页面拦截的添加
- .anyRequest().authenticated()
- .and()
- .formLogin()
- .loginPage("/index/login").permitAll()//这里程序默认路径就是登陆页面,允许所有人进行登陆
- .loginProcessingUrl("/j_spring_security_check")//登陆提交的处理url
- .usernameParameter("j_username")//登陆用户名参数
- .passwordParameter("j_password")//登陆密码参数
- .failureUrl("/index/login?error=true")//登陆失败进行转发,这里回到登陆页面,参数error可以告知登陆状态
- .defaultSuccessUrl("/index/show")//登陆成功的url,这里去到个人首页
- .and().logout().logoutUrl("/j_spring_security_logout").permitAll().logoutSuccessUrl("/index/login?logout=true")//按顺序,第一个是登出的url,security会拦截这个url进行处理,所以登出不需要我们实现,第二个是登出url,logout告知登陆状态
- .and()
- .addFilter(myUsernamePasswordAuthenticationFilter)
- .rememberMe()
- .tokenValiditySeconds(604800)//记住我功能,cookies有限期是一周
- .and()
- .csrf().disable();
- }
- @Override
- public void configure(WebSecurity web) throws Exception{
- super.configure(web);
- }
- @Override
- public void configure(AuthenticationManagerBuilder auth) throws Exception{
- auth.userDetailsService(userDetailService);
- }
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
- }
- 接下来是Service层的代码(UserDetailService.java)
- @Service
- public class UserDetailService implements UserDetailsService {
- @Autowired
- private UserDetailsDao userDetailsDao;
- /**
- * 获取所属角色
- */
- public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
- //查出用户名、密码、角色信息
- Users users = userDetailsDao.getUserByName(username);
- if (users==null) {
- throw new UsernameNotFoundException("找不到该账户信息!");
- }
- List<GrantedAuthority> list = new ArrayList<GrantedAuthority>(); //GrantedAuthority是security提供的权限类,
- list.add(new SimpleGrantedAuthority("ROLE_"+users.getRoles()));
- User auth_user = new User(users.getUsername(), users.getPassword(), list);
- return auth_user;
- }
- }
- 前端代码 .ftl文件(在此只粘出一部分代码,只显示一下用法)
在ftl文件头部加上,引入Security文件
<#assign sec=JspTaglibs["http://www.springframework.org/security/tags"]/>
- <#--没有登录时 能看到买家、卖家所有信息-->
- <@sec.authorize ifNotGranted="ROLE_ADMIN,ROLE_MAIJIA,ROLE_SELLER,ROLE_BOTHSM">
- <dl>
- <dt><a href="/jt/success/orderlist?page=1&orderPeriod=threemonth&orderType=allorder">买家中心</a></dt>
- <dd>
- <a href="/jt/success/orderlist?page=1&orderPeriod=threemonth&orderType=allorder">全部订单</a>
- <a href="#">优惠券</a> <br />
- <a href="/jt/cart/show" class="shoppingCart">我的购物车</a>
- <a href="/jt/favorite/myfavorites/1/time">我的收藏</a>
- </dd>
- </dl>
- <dl>
- <dt><a href="/jt/sellercenter/allproduct?page=1&fenleiId=allproduct">卖家中心</a> </dt>
- <dd>
- <a href="/jt/seller/soldprolist?page=1&orderPeriod=threemonth&orderType=allorder">已卖出货品</a>
- <a href="/jt/release/release1">发布供应产品</a><br />
- <a href="/jt/sellercenter/allproduct?page=1&fenleiId=allproduct">管理供应产品</a>
- <a href="/jt/news/toNewsReleaseListSeller?currentPage=1&newsStatus=2">发布公告</a>
- </dd>
- </dl>
- </@sec.authorize>
- <#--登陆后,买家中心 只有以买家身份登录可以看到-->
- <@sec.authorize ifAnyGranted="ROLE_MAIJIA">
- <dl>
- <dt><a href="/jt/success/orderlist?page=1&orderPeriod=threemonth&orderType=allorder">买家中心</a></dt>
- <dd>
- <a href="/jt/success/orderlist?page=1&orderPeriod=threemonth&orderType=allorder">全部订单</a>
- <a href="#">优惠券</a> <br />
- <a href="/jt/cart/show" class="shoppingCart">我的购物车</a>
- <a href="/jt/favorite/myfavorites/1/time">我的收藏</a>
- </dd>
- </dl>
- </@sec.authorize>
- <#--登陆后,卖家中心 只有以卖家身份登录可以看到-->
- <@sec.authorize ifAnyGranted="ROLE_SELLER">
- <dl>
- <dt><a href="/lbt/sellercenter/allproduct?page=1&fenleiId=allproduct">卖家中心</a> </dt>
- <dd>
- <a href="/lbt/seller/soldprolist?page=1&orderPeriod=threemonth&orderType=allorder">已卖出货品</a>
- <a href="/lbt/release/release1">发布供应产品</a><br />
- <a href="/lbt/sellercenter/allproduct?page=1&fenleiId=allproduct">管理供应产品</a>
- <a href="/lbt/news/toNewsReleaseListSeller?currentPage=1&newsStatus=2">发布公告</a>
- </dd>
- </dl>
- </@sec.authorize>
五、附加知识点:
页面标签的使用与权限配置相对应
authorize标签判断顺序是: access->url->ifNotGranted->ifAllGranted->ifAnyGranted
但他们的关系是“与”: 即只要其中任何一个属性不满足则该标签中间的内容将不会显示给用户,举个例子:
<sec:authorize ifAllGranted=”ROLE_ADMIN,ROLE_MEMBER” ifNotGranted=”ROLE_SUPER”>满足才会显示给用户 </sec:authorize>
标签中间的内容只有在当前用户拥有ADMIN,MEMBER角色,但不拥有SUPER权限时才会显示!
access属性是基于角色判断,url属性是基于访问路径判断。
对于ifAllGranted ,ifNotGranted,ifAnyGranted属性的理解可以与集合api类比
Collection grantedAuths :当前用户拥有的权限
Collection requiredAuths : 当前要求的权限,即ifAllGranted ,ifNotGranted,ifAnyGranted 属性的值满足ifAllGranted: 只需要grantedAuths.containsAll(requiredAuths);返回true即可
满足ifAnyGranted: 只需要grantedAuths.retainAll(requiredAuths);有内容即可(两集合有交集)
满足ifNotGranted:与Any相反,如果没有交集即可
Spring Security 整合freemaker 实现简单登录和角色控制的更多相关文章
- Spring Security 整合 微信小程序登录的思路探讨
1. 前言 原本打算把Spring Security中OAuth 2.0的机制讲完后,用小程序登录来实战一下,发现小程序登录流程和Spring Security中OAuth 2.0登录的流程有点不一样 ...
- Spring Security整合JWT,实现单点登录,So Easy~!
前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...
- spring security整合QQ登录
最近在了解第三方登录的内容,尝试对接了一下QQ登录,此次记录一下如何实现QQ登录的过程,在这个例子中是和spring secuirty整合的,不整合spring secuirty也是一样的. 需求: ...
- Spring Security 集成CAS实现单点登录
参考:http://elim.iteye.com/blog/2270446 众所周知,Cas是对单点登录的一种实现.本文假设读者已经了解了Cas的原理及其使用,这些内容在本文将不会讨论.Cas有Ser ...
- Spring Security 解析(四) ——短信登录开发
Spring Security 解析(四) -- 短信登录开发 在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring Security ...
- Spring Security(02)——关于登录
目录 1.1 form-login元素介绍 1.1.1 使用自定义登录页面 1.1.2 指定登录后的页面 1.1.3 指定登录失败后的页面 1.2 http-basi ...
- Spring Security(17)——基于方法的权限控制
目录 1.1 intercept-methods定义方法权限控制 1.2 使用pointcut定义方法权限控制 1.3 使用注解定义方法权限控制 1.3.1 JSR-25 ...
- spring boot:spring security整合jwt实现登录和权限验证(spring boot 2.3.3)
一,为什么使用jwt? 1,什么是jwt? Json Web Token, 它是JSON风格的轻量级的授权和身份认证规范, 可以实现无状态.分布式的Web应用授权 2,jwt的官网: https:// ...
- Spring Security整合企业微信的扫码登录,企微的API震惊到我了
本文代码: https://gitee.com/felord/spring-security-oauth2-tutorial/tree/wwopen/ 现在很多企业都接入了企业微信,作为私域社群工具, ...
随机推荐
- # 20175333曹雅坤《Java程序设计》第五周学习总结
教材学习内容总结 第六章要点: 1.接口:1)接口声明: interface //接口的名字 2)接口体 2.实现接口:类实现接口:一个类需要在类声明中使用关键字implements声明该类实现一个或 ...
- git知识总结-1.git基础之git分布式
1.前言 我们在介绍git版本管理的时候,没有提到“服务器”的概念,所有的版本管理操作,都是在本地进行的.这就是git与其它版本管理工具(如CVS.SVN等)最本质的区别所在:分布式. 所谓的分布式, ...
- Linux Input子系统浅析(二)-- 模拟tp上报键值【转】
转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...
- 开头不讲"Hello Word",读尽诗书也枉然 : Word 操作组件介绍 - Spire.Doc (转)
[原文地址]http://www.cnblogs.com/liqingwen/p/5898368.html 序 本打算过几天简单介绍下组件 Spire.XLS,突然发现园友率先发布了一篇,既然 x ...
- xPath Helper插件
xPath Helper插件 xPath helper是一款Chrome浏览器的开发者插件,安装了xPath helper后就能轻松获取HTML元素的xPath,程序员就再也不需要通过搜索html源代 ...
- Python爬虫基础之Cookie
一.Cookie会话 简单地说,cookie就是存储在用户浏览器中的一小段文本文件.Cookies是纯文本形式,它们不包含任何可执行代码.一个Web页面或服务器告之浏览器来将这些信息存储并且基于一系列 ...
- C#获取指定的文件是否是内部特殊版本的代码
把内容过程经常用到的内容片段珍藏起来,下面的内容内容是关于C#获取指定的文件是否是内部特殊版本的内容,希望对各朋友有所用处. using System;using System.Diagnostics ...
- 导出pip安装的所有放入一个文件中,并把通过这个安装所有的包
导出pip安装的所有的包: pip freeze > piplist.txt 在新的环境中安装导出的包 pip install -r piplist.txt
- OpenCV-Python:轮廓
啥叫轮廓 轮廓是一系列相连的点组成的曲线,代表了物体的基本外形. 轮廓与边缘很相似,但轮廓是连续的,边缘并不全都连续,其实边缘主要是作为图像的特征使用,比如用边缘特征可以区分脸和手,而轮廓主要用来分析 ...
- PLSQL僵死
同样的SQL语句,同一数据库,但在不同的PLSQL中执行,出现僵死的问题. 修改SQLNET.ORA文件的SQLNET.EXPIRE_TIME值为10,10为默认值.