Spring Security 整合freemaker 实现简单登录和角色控制

Stella981
• 阅读 406

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 坐标:
  1. org.springframework.security

  2. spring-security-core

  3. 3.2.0.RELEASE

  4. org.springframework.security

  5. spring-security-web

  6. 3.2.0.RELEASE

  7. org.springframework.security

  8. spring-security-config

  9. 3.2.0.RELEASE

  10. org.springframework.security

  11. spring-security-taglibs

  12. 3.2.0.RELEASE

  • 在web.xml中配置Security

 

  1. springSecurityFilterChain

  2. org.springframework.web.filter.DelegatingFilterProxy

  3. springSecurityFilterChain

  4. /*

  • Controller文件代码 (SecurityConfig.java)
  1. @Configuration

  2. @EnableWebSecurity

  3. @Component

  4. public class SecurityConfig extends WebSecurityConfigurerAdapter {

  5. @Autowired

  6. private UserDetailService userDetailService;

  7. @Override

  8. protected void configure(HttpSecurity http) throws Exception{

  9. http.authorizeRequests()

  10. .antMatchers( "/index/show").hasAnyRole("ADMIN","BUYER","SELLER")//个人首页只允许拥有ADMIN,BUYER,SELLER角色的用户访问

  11. .antMatchers( "/cart/show").hasAnyRole("ADMIN","MAIJIA","SELLER")

  12. //在此后面可以根据自己的项目需要进行页面拦截的添加

  13. .anyRequest().authenticated()

  14. .and()

  15. .formLogin()

  16. .loginPage( "/index/login").permitAll()//这里程序默认路径就是登陆页面,允许所有人进行登陆

  17. .loginProcessingUrl( "/j_spring_security_check")//登陆提交的处理url

  18. .usernameParameter( "j_username")//登陆用户名参数

  19. .passwordParameter( "j_password")//登陆密码参数

  20. .failureUrl( "/index/login?error=true")//登陆失败进行转发,这里回到登陆页面,参数error可以告知登陆状态

  21. .defaultSuccessUrl( "/index/show")//登陆成功的url,这里去到个人首页

  22. .and().logout().logoutUrl( "/j_spring_security_logout").permitAll().logoutSuccessUrl("/index/login?logout=true")//按顺序,第一个是登出的url,security会拦截这个url进行处理,所以登出不需要我们实现,第二个是登出url,logout告知登陆状态

  23. .and()

  24. .addFilter(myUsernamePasswordAuthenticationFilter)

  25. .rememberMe()

  26. .tokenValiditySeconds( 604800)//记住我功能,cookies有限期是一周

  27. .and()

  28. .csrf().disable();

  29. }

  30. @Override

  31. public void configure(WebSecurity web) throws Exception{

  32. super.configure(web);

  33. }

  34. @Override

  35. public void configure(AuthenticationManagerBuilder auth) throws Exception{

  36. auth.userDetailsService(userDetailService);

  37. }

  38. @Override

  39. public AuthenticationManager authenticationManagerBean() throws Exception {

  40. return super.authenticationManagerBean();

  41. }

  42. }

  • 接下来是Service层的代码(UserDetailService.java)
  1. @Service

  2. public class UserDetailService implements UserDetailsService {

  3. @Autowired

  4. private UserDetailsDao userDetailsDao;

  5. /**

  6. * 获取所属角色

  7. */

  8. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

  9. //查出用户名、密码、角色信息

  10. Users users = userDetailsDao.getUserByName(username);

  11. if (users==null) {

  12. throw new UsernameNotFoundException("找不到该账户信息!");

  13. }

  14. List list = new ArrayList(); //GrantedAuthority是security提供的权限类,

  15. list.add( new SimpleGrantedAuthority("ROLE_"+users.getRoles()));

  16. User auth_user = new User(users.getUsername(), users.getPassword(), list);

  17. return auth_user;

  18. }

  19. }

  • 前端代码 .ftl文件(在此只粘出一部分代码,只显示一下用法)

       在ftl文件头部加上,引入Security文件

<#assign sec=JspTaglibs["http://www.springframework.org/security/tags"]/>
  1. <#--没有登录时 能看到买家、卖家所有信息-->

  2. < @sec.authorize ifNotGranted="ROLE_ADMIN,ROLE_MAIJIA,ROLE_SELLER,ROLE_BOTHSM">

  3. 买家中心
  4. 全部订单

  5. 优惠券

  6. 我的购物车

  7. 我的收藏

  8. 卖家中心
  9. 已卖出货品

  10. 发布供应产品

  11. 管理供应产品

  12. 发布公告

  13. </ @sec.authorize>

  14. <#--登陆后,买家中心 只有以买家身份登录可以看到-->

  15. < @sec.authorize ifAnyGranted="ROLE_MAIJIA">

  16. 买家中心
  17. 全部订单

  18. 优惠券

  19. 我的购物车

  20. 我的收藏

  21. </ @sec.authorize>

  22. <#--登陆后,卖家中心 只有以卖家身份登录可以看到-->

  23. < @sec.authorize ifAnyGranted="ROLE_SELLER">

  24. 卖家中心
  25. 已卖出货品

  26. 发布供应产品

  27. 管理供应产品

  28. 发布公告

  29. </ @sec.authorize>

五、附加知识点:

页面标签的使用与权限配置相对应

authorize标签判断顺序是: access->url->ifNotGranted->ifAllGranted->ifAnyGranted

但他们的关系是“与”: 即只要其中任何一个属性不满足则该标签中间的内容将不会显示给用户,举个例子:

<sec:authorize  ifAllGranted=”ROLE_ADMIN,ROLE_MEMBER” ifNotGranted=”ROLE_SUPER”>满足才会显示给用户

标签中间的内容只有在当前用户拥有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相反,如果没有交集即可

点赞
收藏
评论区
推荐文章
kenx kenx
2年前
SpringBoot之SpringSecurity权限注解在方法上进行权限认证多种方式
前言SpringSecurity支持方法级别的权限控制。在此机制上,我们可以在任意层的任意方法上加入权限注解,加入注解的方法将自动被SpringSecurity保护起来,仅仅允许特定的用户访问,从而还到权限控制的目的,当然如果现有的权限注解不满足我们也可以自定义快速开始1.首先加入security依赖如下xmlorg.springframe
徐小夕 徐小夕
3年前
用css3实现惊艳面试官的背景即背景动画(高级附源码
我们传统的前端更多的是用javascript实现各种复杂动画,自从有了Css3transition和animation以来,前端开发在动画这一块有了更高的自由度和格局,对动画的开发也越来越容易。这篇文章就让我们汇总一下使用Css3实现的各种特效。这篇文章参考《css揭秘》这本书,并作出了自己的总结,希望能让大家更有收获,也强烈推荐大家看看这本书,你值得拥有
Wesley13 Wesley13
2年前
RBAC模型
RBAC基于角色的访问控制(RoleBasedAccessControl)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用
Wesley13 Wesley13
2年前
CAS 4.1.x 单点登出(退出登录)的原理解析
  我们在项目中使用了cas作为单点登录的解决方案,当在集成shiro做统一权限控制的时候,发现单点退出登录有坑,所以啃了一下CAS的单点登出的源码,在此分享一下。1、回顾单点登录中一些关键事件  在解析CAS单点登出的原理之前,我们先回顾一下在单点登录过程中,CAS服务器和CAS客户端都做了一些什么事,这些事
Stella981 Stella981
2年前
Apache Sentry实战之旅(一)—— Impala+Sentry整合
Impala默认是以impala这个超级用户运行服务,执行DML和DDL操作的,要实现不同用户之间细粒度的权限控制,需要与Sentry整合。Sentry是Apache下的一个开源项目,它基于RBAC的授权模型实现了权限控制,Impala与它整合以后,就能实现不同用户之间在应用层的权限认证,从而控制用户的DML、DDL
Stella981 Stella981
2年前
Spring+SpringMVC+Mybatis+Mysql整合实例【转】
本文要实现SpringSpringMVCMybatisMysql的一个整合,实现了SpringMVC控制访问的页面,将得到的页面参数传递给Spring中的Mybatis的bean类,然后查找Mysql数据的功能,并通过JSP显示出来。建议可以先看笔者另一文章Mybatis与Spring整合创建Web项目 。笔者觉得整合过程中问题比较多的还是Spring
Stella981 Stella981
2年前
Spring Security OAuth2 SSO
通常公司肯定不止一个系统,每个系统都需要进行认证和权限控制,不可能每个每个系统都自己去写,这个时候需要把登录单独提出来1.登录和授权是统一的2.业务系统该怎么写还怎么写!(https://oscimg.oschina.net/oscnet/87496320180711181735072935217297.png)
Stella981 Stella981
2年前
Spring3.1.0实现原理分析(二十一).Dao事务分析之集成MyBatis
    大家好,这篇博客我想分析下Spring是如何集成myBatis的,下篇博客分析集成后DataSourceTransactionManager事务管理的完整流程。spring集成mybatis,spring主要扮演了两个角色,原料供应商和事务管理者,第一个角色是必须扮演的,第二个角色可选,事务也可以由mybatis自己管理。为什么说第一个角色叫原
Stella981 Stella981
2年前
PostgreSQL学习手册(十) 角色和权限
 PostgreSQL是通过角色来管理数据库访问权限的,我们可以将一个角色看成是一个数据库用户,或者一组数据库用户。角色可以拥有数据库对象,如表、索引,也可以把这些对象上的权限赋予其它角色,以控制哪些用户对哪些对象拥有哪些权限。    一、数据库角色:   1\.创建角色:   CREATEROLE
Stella981 Stella981
2年前
Spring Security修炼手册(四)————Security默认表达式的权限控制
       前三章主要讲的是Security对于认证的处理,那么本节,会为大家介绍基于Security默认表达式的权限控制(较为简单,无法满足复杂权限控制及多变的权限规则,后面会介绍基于自定义表达式的权限访问控制,可满足99%的业务场景的需求)。一、介绍及使用 直接进入主题,基于默认的表达式权限控制,需要在SecurityConf