前言

本来是打算在上一篇SpringMVC+Hibernate上写的,结果发现上面那篇一起整合的,结果发现上一篇内容实在是太长了,就另起一篇,这篇主要是采用 Maven搭建Spring+SpringMVC+Hibernate+Security整合,而Spring+SpringMVC+Hibernate已经在上一篇介绍了,在这篇将不再重复写了,主要说明一下SpringSecurity3.2权限控制整合搭建,以及配置,使用注意事项等。

SpringSecurity的Api文档地址:查看

1、Maven映入SpringSecurity依赖包

在pom.xml中引入我们需要引入spring-security-core,spring-security-config,spring-security-taglibs三个包,如下

               <!-- spring-security --><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-core</artifactId><version>${security.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>${security.version}</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>${security.version}</version></dependency>

2、配置security的配置文件

我们新建一个配置文件(起名随意),我这儿就叫spring-security.xml,我现在定义了几个权限,权限信息表内容如下:

其中:管理用户和全部用户的权限将通过jsp中security标签配置,其他的通过spring-security.xml文件配置。

先贴出spring-security.xml的文件,详细配置含义我将做一个简单的说明:

<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:security="http://www.springframework.org/schema/security"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsdhttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"default-lazy-init="true"><description>spring-security配置</description><!-- 静态资源 --><security:http pattern="/css/**" security="none" /><security:http pattern="/js/**" security="none" /><security:http pattern="/images/**" security="none" /><security:http><security:intercept-url pattern="/user/save*"access="ROLE_添加用户" requires-channel="any" /><security:intercept-url pattern="/user/delete*"access="ROLE_删除用户" requires-channel="any" /><security:intercept-url pattern="/user/user*"access="ROLE_浏览用户" requires-channel="any" /><security:intercept-url pattern="/user/update*"access="ROLE_修改用户" requires-channel="any" /><security:session-management><security:concurrency-controlexpired-url="/login/login.htmls?repeat=true" max-sessions="1"error-if-maximum-exceeded="true" /></security:session-management><security:form-login login-page="/login/login.htmls"authentication-failure-url="/login/login.htmls?error=true"default-target-url="/user/main.htmls" always-use-default-target='true'username-parameter="nickName" password-parameter="nickPassword" /><security:logout invalidate-session="true"logout-success-url="/login/login.htmls?logout=true" /></security:http><!-- 认证配置 自定义认证实现UserDetailsService接口 --><security:authentication-manager><security:authentication-provideruser-service-ref="userDetailsService"><!-- 配置密码加密方式 --><security:password-encoder hash="md5" /></security:authentication-provider></security:authentication-manager><bean id="userDetailsService" class="org.andy.work.service.impl.UserDetailsServiceImpl" /></beans></span>

其中:我们配置了静态文件管理,session对话管理,登录管理,注销配置,权限配置,自定义数据表权限认证配置。

2.1、静态文件管理

我们对于css,image,js这些不用权限拦截。

2.2、session对话管理

session管理max-sessions="1"配置了最多有一个用户登录,(在wab.xml还要添加如下:)

<span style="font-size:14px;"><!-- spring-security 管理session配置 --><listener><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener></span>

error-if-maximum-exceeded="true"  值为true时,若果有一个用户登录,第二个用户无法登陆,

值为false时,若果有一个用户已经登录,下一个用户登录将踢掉上一个用户。

自然在session-manager中我们可以配置session失效时,跳转的url如,invalid-session-url="/invalidSession.jsp",如果session失效时,刷新将跳转到invalidSession.jsp页面。

2.3、登录管理

通过security:form-login配置登录,login-page为登录跳转的url,authentication-failure-url为登录失败时的url(次url可以不存在),

username-parameter和password-parameter为登录表单是用户名和密码,如果不写默认为j_password和j_username

login-processing-url:为登录时表单action跳转的url,如果不填写默认为 j_spring_security_check。

2.4、注销管理

通过security:logout标签配置注销,invalidate-session:注销时session是否失效。logout-success-url:注销成功后跳转的地址。

logout-url:为注销的url,如果不填写,则默认为j_spring_security_logout

2.5、权限配置

security:intercept-url为要拦截权限认证的的url,pattern为拦截的正则匹配url,access:所需的权限,可以是一个权限组,用逗号隔开,requires-channel:拦截http还是https的,如果两个都拦截用any。

2.6、配置自定义的权限认证机制

通过我们数据库的权限表信息,我们自定义权限认证机制,需要我们实现UserDetailsService接口,配置用户密码的加密方式。

security:password-encoder:配置密码加密规则。

3、web.xml容器配置

<span style="font-size:14px;">         <context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring.xmlclasspath:spring-hibernate.xmlclasspath:spring-security.xml</param-value></context-param><!-- Spring-Security filter 最好配置在控制层filter的前面 --><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><!-- spring-security 管理session配置 --><listener><listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class></listener></span>

配置了加载的spring-security文件,security拦截的filter,以及security的session监听。

4、自定义认证,实现UserDetailsService接口

UserDetailsServiceImpl如下:

<span style="font-size:14px;">package org.andy.work.service.impl;import java.util.HashSet;
import java.util.Set;import org.andy.work.dao.UserDao;
import org.andy.work.entity.AcctAuthority;
import org.andy.work.entity.AcctRole;
import org.andy.work.entity.AcctUser;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;/*** 创建时间:2015-2-9 下午5:24:44* * @author andy* @version 2.2*          <p>*          描述: 实现SpringSecurity的UserDetails接口 自定义认证*/public class UserDetailsServiceImpl implements UserDetailsService {private static final Logger LOGGER = Logger.getLogger(UserDetailsServiceImpl.class);// 注入查询User的dao层@Autowiredprivate UserDao userDao;@Overridepublic UserDetails loadUserByUsername(String username)throws UsernameNotFoundException {LOGGER.info("认证用户:" + username);// 查询数据库获取改用户的信息AcctUser acctUser = userDao.findByNickName(username);if (null == acctUser) {throw new UsernameNotFoundException("用户:" + username + "不存在");}Set<GrantedAuthority> authorities = getAuthorities(acctUser);// 将没有使用到的属性设置为trueUserDetails userDetails = new User(acctUser.getNickName(),acctUser.getNickPassword(), true, true, true, true, authorities);return userDetails;}// 获得用户所有角色的权限private Set<GrantedAuthority> getAuthorities(AcctUser acctUser) {Set<GrantedAuthority> authoritySet = new HashSet<GrantedAuthority>();// 默认所有的用户有"浏览用户"的权利authoritySet.add(new SimpleGrantedAuthority("ROLE_浏览用户"));// 依次添加if (null != acctUser.getAcctRoles()&& acctUser.getAcctRoles().size() > 0)for (AcctRole role : acctUser.getAcctRoles()) {if (null != role.getAcctAuthorities()&& role.getAcctAuthorities().size() > 0)for (AcctAuthority authority : role.getAcctAuthorities()) {authoritySet.add(new SimpleGrantedAuthority(authority.getPrefixedName()));}}return authoritySet;}}
</span>

涉及到的AcctUser,AcctRole,AcctAuthority类我就不贴了,不然一大把,我会提供源码。

5、Security的认证错误提示

我们可以通过sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message获取认证错误。

6、Security获取session中的用户名和用户信息

security将用户信息存放在session中,可以通过以下两种获得:

6.1、后台获取

<span style="font-size:14px;">      //获取security的上下文SecurityContext securityContext = SecurityContextHolder.getContext();//获取认证对象Authentication authentication = securityContext.getAuthentication();//在认证对象中获取主体对象Object principal = authentication.getPrincipal();String username = "";if(principal instanceof UserDetails){username = ((UserDetails) principal).getUsername();}else {username = principal.toString();}</span>

6.1、前台获取

先引入security的标签库:

<span style="font-size:14px;"><%@taglib prefix="security" uri="http://www.springframework.org/security/tags"%></span>

在查看:

<span style="font-size:14px;"><security:authentication property="name"/></span>

7、前台标签授权

通过security:authorize标签设置权限,其有三种属性分别如下:

ifAnyGranted::只有当前用户拥有所指定的权限中的一个的时候,就能显示标签内部的内容(相当于“或”的关系)

ifAllGranted:只有当前用户拥有所指定的权限时,才显示标签的内容(相当于“与”的关系)

ifNotGranted:  没有指定的权限的时候,显示标签内容(相当于“非”的关系)

自然也可以通过method限制是那种http的请求(http的请求有8种:- GET - DELETE - HEAD - OPTIONS    - POST     - PUT    - PATCH    - TRACE)。

8、后台Controller

LoginController

<span style="font-size:14px;"><span style="font-size:14px;">package org.andy.work.controller;import org.andy.work.entity.AcctUser;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;/*** 创建时间:2015-2-10 下午9:23:34* * @author andy* @version 2.2 描述:*/
@Controller
@RequestMapping("/login")
public class LoginController {private static final Logger LOGGER = Logger.getLogger(LoginController.class);@RequestMapping("/login")public String login(@ModelAttribute AcctUser acctUser,@RequestParam(required = false) Boolean logout,Errors errors) {LOGGER.info("login");if(null != logout){errors.reject("msg", "已经安全退出");}return "/login/login";}}</span>
</span>

UserController类

<span style="font-size:14px;">package org.andy.work.controller;import java.util.List;import org.andy.work.entity.AcctUser;
import org.andy.work.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/**  * 创建时间:2015-2-7 上午11:49:00  * @author andy  * @version 2.2  * 描述: 用户Controller*/
@Controller
@RequestMapping("/user")
public class UserController {private static final Logger LOGGER = Logger.getLogger(UserController.class);@Autowiredprivate UserService userService;@RequestMapping("/showInfo/{userId}")public String showUserInfo(ModelMap modelMap, @PathVariable String userId){LOGGER.info("查询用户:" + userId);AcctUser userInfo = userService.load(userId);modelMap.addAttribute("userInfo", userInfo);return "/user/showInfo";}@RequestMapping("/showInfos")public @ResponseBody List<AcctUser> showUserInfos(){LOGGER.info("查询用户全部用户");List<AcctUser> userInfos = userService.findAll();return userInfos;}@RequestMapping("/main")public String main(ModelMap modelMap){LOGGER.info("显示主页面");//后台获取security保存的session中的用户信息//获取security的上下文SecurityContext securityContext = SecurityContextHolder.getContext();//获取认证对象Authentication authentication = securityContext.getAuthentication();//在认证对象中获取主体对象Object principal = authentication.getPrincipal();String username = "";if(principal instanceof UserDetails){username = ((UserDetails) principal).getUsername();}else {username = principal.toString();}modelMap.addAttribute("username", username);return "/user/main";}@RequestMapping("/manage")public String manage(ModelMap modelMap){LOGGER.info("显示主页面");modelMap.addAttribute("msg", "manage");return "/user/option";}@RequestMapping("/save")public String save(ModelMap modelMap){LOGGER.info("保存");modelMap.addAttribute("msg", "save");return "/user/option";}@RequestMapping("/update")public String update(ModelMap modelMap){LOGGER.info("修改");modelMap.addAttribute("msg", "update");return "/user/option";}@RequestMapping("/delete")public String delete(ModelMap modelMap){LOGGER.info("删除");modelMap.addAttribute("msg", "delete");return "/user/option";}}
</span>

9、前台

login.jsp

<span style="font-size:14px;"><%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%><%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>login</title>
</head>
<body><div>${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}</div><form:form action="j_spring_security_check" modelAttribute="acctUser" method="post"><form:errors path="*" cssStyle="color:red;" /><br />用户:<form:input path="nickName" /><br />密码:<form:password path="nickPassword" /><br /><form:button>登录</form:button></form:form>
</body>
</html></span>

main.jsp

<span style="font-size:14px;"><%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@taglib prefix="security" uri="http://www.springframework.org/security/tags"%><%String path = request.getContextPath();String basePath = request.getScheme() + "://"+ request.getServerName() + ":" + request.getServerPort()+ path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<base href="<%=basePath%>" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>login</title>
</head>
<body>welcome! <security:authentication property="name"/><br/>后台获取用户名:${username }<div style="border: 1px; "><a target="_blank" href="j_spring_security_logout">注销</a></div><br/><security:authorize ifAnyGranted="ROLE_浏览用户"><div><a target="_blank" href="user/showInfo.htmls">全部用户</a></div></security:authorize><security:authorize ifAllGranted="ROLE_管理用户"><div><a target="_blank" href="user/manage.htmls">管理用户</a></div></security:authorize><div><a target="_blank" href="user/save.htmls">添加用户</a></div><div><a target="_blank" href="user/update.htmls">修改部用户</a></div><div><a target="_blank" href="user/delete.htmls">删除用户</a></div></body>
</html></span>

10、测试

现在andy用户拥有“浏览用户”和“添加用户”权限

用户密码错误时:

正确密码登陆后:

点击添加用户,正确跳转。如下:

点击全部用户,无权限提示。

11、Spring security自定义认证错误提示

首先,拷贝spring-security-core写的messages_zh_CN.properties国际化文件,放到项目的src/main/resources目录中

修改对应的提示,按照我们自己的需求,我命名为messages.properties

其次, 我们需在spring的配置文件中添加如下内容:

<span style="font-size:14px;"><span style="font-size:14px;">   <!-- 定义上下文返回的消息的国际化 --><bean id="messageSource"class="org.springframework.context.support.ReloadableResourceBundleMessageSource"><property name="basename" value="classpath:messages" /></bean><bean id="localeResolver"class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" /></span></span>

ok,Maven搭建Spring+Hibernate+security整合完毕。

后续

遗留问题,通用的重写security提示信息,其他的都能国际化汉语提示,但是

唯独

ConcurrentSessionControlStrategy.exceededAllowed=\u5DF2\u7ECF\u6709 {0} \u4E2A\u7528\u6237\u767B\u5F55\uFF0C\u4E0D\u80FD\u91CD\u590D\u767B\u5F55

我修改重复登录提示时,还是security原来自带的提示,如下:

希望又遇到的共同留言探讨。

博客地址:http://blog.csdn.net/fengshizty

源码地址:http://download.csdn.net/detail/fengshizty/8444061

Maven搭建Spring Security3.2项目详解相关推荐

  1. pycharm创建mysql项目_python+Django+pycharm+mysql 搭建首个web项目详解

    本文实例讲述了python+Django+pycharm+mysql 搭建首个web项目.分享给大家供大家参考,具体如下: 前面的文章记录了环境搭建的过程,本节记录首个web项目调试 首先检查安装的模 ...

  2. Python3 环境搭建、pycharm安装配置详解、新建Python项目(新手小白版Windows系统)

    Python3 环境搭建 .pycharm安装配置详解 window系统上环境搭建: 一.环境搭建,下载Python (Python 3.8为例) 二.pycharm的下载与安装 window系统上环 ...

  3. Maven 搭建spring boot多模块项目(附源码)

    Maven 搭建spring boot多模块项目 备注:所有项目都在idea中创建 1.idea创建maven项目 1-1: 删除src,target目录,只保留pom.xml 1-2: 根目录pom ...

  4. Spring和Security整合详解

    Spring和Security整合详解 一.官方主页 Spring Security 二.概述 Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 基于 Sp ...

  5. Spring和Ehcache整合详解

    Spring和Ehcache整合详解 一.官方主页 Spring Cache 二.概述 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点. Spring 提供了对缓存功能的抽象: ...

  6. java 消息队列详解_Java消息队列-Spring整合ActiveMq的详解

    本篇文章主要介绍了详解Java消息队列-Spring整合ActiveMq ,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 1.概述 首先和大家一起回顾一下Java 消息服 ...

  7. SpringBoot2.1.5(16)--- Spring Boot的日志详解

    SpringBoot2.1.5(16)--- Spring Boot的日志详解 市面上有许多的日志框架,比如 JUL( java.util.logging), JCL( Apache Commons ...

  8. Spring和Redis整合详解

    Spring和Redis整合详解 官方主页 Spring Spring Redis 概述 Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库,缓存和消息代理. 简单来说,它是一个以(ke ...

  9. Spring和WebSocket整合详解

    Spring和WebSocket整合详解 本篇编写日期较早,代码冗余较多,新博文:Spring和WebSocket整合并建立简单的Web聊天室 官方主页 Spring WebSocket 概述 Web ...

  10. Spring和Email整合详解

    Spring和Email整合详解 官方主页 Spring Email 概述 Spring Mail API都在org.springframework.mail及其子包org.springframewo ...

最新文章

  1. 编程术语_伟大的编程术语烘烤
  2. 理解jmeter聚合报告
  3. JVM命令查看与设置参数
  4. 神经网络学习之----Hopfield神经网络(代码实现)
  5. 解决HDFS NameNode启动时Loading edits时间超长的问题(NameNode数据同步机制介绍)
  6. boost::rotate_copy相关的测试程序
  7. JavaScript-Array操作
  8. c# 深拷贝各种实现方式
  9. C#实现图片文件到数据流再到图片文件的转换
  10. mac上sublime配置php环境,Mac下sublime text3如何配置php编译环境?
  11. python旋转地球源代码_90行代码让微信地球转起来,太酷了!(python实现)
  12. 如何查看表或列的所有外键?
  13. 苹果移动设备用什么管理比较好?有什么推荐?
  14. 谷歌员工确诊,全球顶级开发者大会F8取消!WHO将新冠肺炎全球风险级别升至最高...
  15. BeyondCompare3密钥过期如何处理。
  16. 计算机桌面文件自动备份取消,电脑如何取消自动备份_电脑怎么取消自动备份...
  17. 局域网远程桌面无法连接到远程计算机,局域网无法远程连接桌面怎么解决
  18. Android组件化开发,组件间的Activity页面跳转。
  19. 澳洲航空和香港航空在OAG的准点率报告中获得五星评级
  20. 语音信号处理--基音检测实验

热门文章

  1. swift5的下标Subscripts 花式玩法
  2. mysql时间排序获取最新_mysql获取按日期排序获取时间最近的记录
  3. 逻辑回归与线性回归是什么关系呢?
  4. Plus One @python
  5. DeepLab图像分割
  6. 计算机采用二进制码的优点
  7. MFSK以及MFSK和MPSK的对比
  8. java线程期末考试_mooc课程 java 期末考试试卷
  9. python如何设置双索引_python-在新的多索引下串联熊猫列
  10. css 点击效果_纯 CSS 实现吸附效果