SpringSecurity简单应用(二)
这里我首先对我上一篇博文的第三个实例做一下讲解,下面是applicationContext-security.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- 自动配置模式,拦截所有请求,有ROLE_USER才可以通过 -->
<http auto-config="true">
<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- 增加 ROLE_ADMIN角色-->
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
</http>
<!-- 认证管理器。用户名密码都集成在配置文件中 -->
<authentication-manager>
<authentication-provider>
<user-service>
<!-- 添加ROLE_ADMIN角色 -->
<user name="admin" password="admin" authorities="ROLE_USER,ROLE_ADMIN"/>
<user name="sharp" password="sharp" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
<!-- 指定中文资源 。默认命名空间是security,所以要加前缀beans: -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/>
</beans:bean>
</beans:beans>
该配置文件的注解如下:
- <http auto-config="true">,这一部分是配置如何拦截用户请求,auto-config="true"将自动配置几个常用的权限机制,包括form,anonymous,rememberMe.(这几种机制我也不太不明白) 。
- 我们利用intercept-url来判断用户需要何种权限才能访问对应的url资源,可以在pattern中指定一个特定的url资源,也可以使用通配符来指定一组类似的url资源。例子中定义的两个intercepter-url,第一个用来控制对/admin.jsp的访问,第二个使用了通配符/**,说明它将控制对系统中所有url资源的访问。在实际使用中,Spring Security采用的是一种就近原则,就是说当用户访问的url资源满足多个intercepter-url时,系统将使用第一个符合条件的intercept-url进行权限控制。在我们这个例子中就是,当用户访问/admin.jsp时,虽然两个intercept-url都满足要求,但因为第一个intercept-url排在上面,所以Spring Security会使用第一个intercept-url中的配置处理对/admin.jsp的请求,也就是说,只有那些拥有了ROLE_ADMIN权限的用户才能访问/admin.jsp。access指定的权限部分比较有趣,大家可以注意到这些权限标示符都是以ROLE_开头的,实际上这与Spring Security中的Voter机制有着千丝万缕的联系,只有包含了特定前缀的字符串才会被Spring Security处理。目前来说我们只需要记住这一点就可以了,在我文章以后的部分中我们会详细讲解Voter的内容。(这里就解释了我在上面一个文章里,sharp拥有/**所有页面权限,为什么sharp用户却不能访问admin.jsp的原因)
user-service中定义了两个用户,admin和user。为了简便起见,我们使用明文定义了两个用户对应的密码,这只是为了当前演示的方便,之后的例子中我们会使用Spring Security提供的加密方式,避免用户密码被他人窃取。最最重要的部分是authorities,这里定义了这个用户登陆之后将会拥有的权限,它与上面intercept-url中定义的权限内容一一对应。每个用户可以同时拥有多个权限,例子中的admin用户就拥有ROLE_ADMIN和ROLE_USER两种权限,这使得admin用户在登陆之后可以访问ROLE_ADMIN和ROLE_USER允许访问的所有资源。与之对应的是,user用户就只拥有ROLE_USER权限,所以他只能访问ROLE_USER允许访问的资源,而不能访问ROLE_ADMIN允许访问的资源。
第四个实例:
这个实例里面用户信息存入到数据库里,我使用的是数据库是Oracle,如下:
create table USERS
(
USERNAME VARCHAR2(64) not null,
PASSWORD VARCHAR2(64),
ENABLED NUMBER
)
comment on column USERS.USERNAME
is '用户名';
comment on column USERS.PASSWORD
is '密码';
comment on column USERS.ENABLED
is '0--不可用;1--可用';
alter table USERS
add constraint PK_USERS primary key (USERNAME) create table AUTHORITIES
(
USERNAME VARCHAR2(64) not null,
AUTHORITY VARCHAR2(64) not null
)
tablespace ANDROIDXIAJUN
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table AUTHORITIES
add constraint INDEX_USER_AUTH unique (USERNAME, AUTHORITY)
alter table AUTHORITIES
add constraint USER_AUTHORITIES_FK foreign key (USERNAME)
references USERS (USERNAME);
数据库表创建好后,我们插入一些测试数据:
insert into users(username,password,enabled) values('admin','admin',1);
insert into users(username,password,enabled) values('sharp','sharp',1);
insert into authorities(username,authority) values('admin','ROLE_ADMIN');
insert into authorities(username,authority) values('admin','ROLE_USER');
insert into authorities(username,authority) values('sharp','ROLE_USER');
数据库的表建好,里面数据也有了,接下来就是修改我们原来的程序了。前面的三个实例都是在配置文件里配置好用户信息,而且还是明文的,如果换成数据库我们只要把这个部分的内容更改下:
<!-- 认证管理器。用户名密码都集成在配置文件中 -->
<authentication-manager>
<authentication-provider>
<user-service>
<!-- 添加ROLE_ADMIN角色 -->
<user name="admin" password="admin" authorities="ROLE_USER,ROLE_ADMIN"/>
<user name="sharp" password="sharp" authorities="ROLE_USER"/>
</user-service>
</authentication-provider>
</authentication-manager>
修改的新内容是:
<!-- 认证管理器。用户名密码从数据库里读取 -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
另外我们还要增加一个数据源dataSource,没有增加其他配置,那么用户服务默认将会使用如下的SQL语句来查询用户信息:
select username,password,enabled from users where username = ?
默认情况下会使用下面的SQL语句来查询指定用户名的权限:
select username,authority from authorities where username = ?
下面是我修改后完整的applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- 自动配置模式,拦截所有请求,有ROLE_USER才可以通过 -->
<http auto-config="true">
<intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- 增加 ROLE_ADMIN角色-->
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1"/>
</http>
<!-- 认证管理器。用户名密码从数据库里读取 -->
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
<!-- 指定中文资源 。默认命名空间是security,所以要加前缀beans: -->
<beans:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:org/springframework/security/messages_zh_CN"/>
</beans:bean>
<!-- 配置数据源信息 -->
<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<beans:property name="driverClass" value="${db.driverClass}"/>
<beans:property name="jdbcUrl" value="${db.jdbcUrl}"/>
<beans:property name="user" value="${db.user}"/>
<beans:property name="password" value="${db.password}"/>
</beans:bean>
<!-- 读取资源文件 -->
<beans:bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<beans:property name="locations">
<beans:list>
<beans:value>classpath:constants.properties</beans:value>
</beans:list>
</beans:property>
</beans:bean>
</beans:beans>
按照我以前开发的习惯的,我会把spring里面很多配置信息放置到constants.properties里面,便于统一管理,constants.properties内容如下:
db.driverClass = oracle.jdbc.driver.OracleDriver
db.user = sharpxiajun
db.password = sharpxiajun
db.jdbcUrl = jdbc:oracle:thin:@127.0.0.1:1521:orcl
为了和数据库链接我又增加了一些jar包
至于测试和前面三个实例一样,这里不做过多表述了。
上一篇文章里,我们做的第二个实例是“自定义登录界面”,对里面一些特别的配置没有进行讲解,下面的内容就是对这个功能的具体讲解了:
<http auto-config="true">
<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<!-- 增加 ROLE_ADMIN角色-->
<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/>
<intercept-url pattern="/**" access="ROLE_USER"/>
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/index.jsp"/>
</http>
1.<intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />让没登陆的用户也可以访问login.jsp。这是因为配置文件中的“/**”配置,要求用户访问任意一个系统资源时,必须拥有ROLE_USER角色,/login.jsp也不例外,如果我们不为/login.jsp单独设置访问权限,会造成用户连登录权限都没有,这个是不正确的
2. <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/index.jsp"/>login-page表示用户登陆时显示我们自定义的login.jsp。这时我们访问系统显示的登陆页面将是我们上面创建的login.jsp。authentication-failure-url表示用户登陆失败时,跳转到哪个页面。当用户输入的登录名和密码不正确时,系统将再次跳转到/login.jsp,并添加一个error=true参数作为登陆失败的标示。default-target-url表示登陆成功时,跳转到哪个页面。
自制的登录页面里也有很多没有做注解的地方,现在补上页面里的注解,页面内容如下:
<body onLoad="document.f.j_username.focus();">
<c:if test="${not empty param.login_error}">
<font color="red">
登录失败,请重试.<br/><br/>
原因:<c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}"/>
</font>
</c:if>
<form name="f" action="<c:url value='j_spring_security_check'/>" method="POST">
<table>
<tr>
<td>用户名:</td>
<td>
<input type='text' name='j_username' value='<c:if test="${not empty param.login_error}"><c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>'/>
</td>
</tr>
<tr>
<td>密 码:</td>
<td><input type='password' name='j_password'></td>
</tr>
<tr>
<td>
<input type="checkbox" name="_spring_security_remember_me"></td><td>两周内自动登录
</td>
</tr>
<tr>
<td colspan='2' align="center">
<input name="submit" type="submit">
<input name="reset" type="reset">
</td>
</tr>
</table>
</form>
</body>
注解如下:
1.<body onload='document.f.j_username.focus();'>
表示在页面装载时onload调用函数'document.f.j_username.focus();该函数的意思是让表单中的j_username获得焦点,即把光标移动到该控件上;
2. action="<c:url value='j_spring_security_check'/>" /j_spring_security_check,提交登陆信息的URL地址。自定义form时,要把form的action设置为/j_spring_security_check。注意这里要使用绝对路径,避免登陆页面存放的页面可能带来的问题。
3. j_username,输入登陆名的参数名称。
4. j_password,输入密码的参数名称
5. _spring_security_remember_me,选择是否允许自动登录的参数名称。
可以直接把这个参数设置为一个checkbox,无需设置value,Spring Security
总结下了:Springsecurity应用讲解暂时告一段落,这个系列主要是为了应付实际工作,并不是我的研究重点,不过我很想在项目里面使用到它,到那时我一定会更加什么的讲解。另外我手头上springsecurity的资料并不太好,没有做深入研究的,如果哪位童鞋有更好的相关资料,希望能跟我分享下。
SpringSecurity简单应用(二)的更多相关文章
- SpringSecurity简单使用
什么是SpringSecurity? Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置 ...
- iOS开发UI篇—Quartz2D简单使用(二)
iOS开发UI篇—Quartz2D简单使用(二) 一.画文字 代码: // // YYtextview.m // 04-写文字 // // Created by 孔医己 on 14-6-10. // ...
- 使用C语言实现二维,三维绘图算法(3)-简单的二维分形
使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...
- 【sql注入】简单实现二次注入
[sql注入]简单实现二次注入 本文转自:i春秋社区 测试代码1:内容详情页面 [PHP] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 1 ...
- VC6下OpenGL 开发环境的构建外加一个简单的二维网络棋盘绘制示例
一.安装GLUT 工具包 GLUT 不是OpenGL 所必须的,但它会给我们的学习带来一定的方便,推荐安装. Windows 环境下的GLUT 本地下载地址:glut-install.zip(大小约为 ...
- Java秒杀简单设计二:数据库表和Dao层设计
Java秒杀简单设计二:数据库表Dao层设计 上一篇中搭建springboot项目环境和设计数据库表 https://www.cnblogs.com/taiguyiba/p/9791431.html ...
- 爬虫简单之二---使用进程爬取起点中文网的六万多也页小说的名字,作者,等一些基本信息,并存入csv中
爬虫简单之二---使用进程爬取起点中文网的六万多也页小说的名字,作者,等一些基本信息,并存入csv中 准备使用的环境和库Python3.6 + requests + bs4 + csv + multi ...
- SignalR的简单使用(二)
原文:SignalR的简单使用(二) 之前提到SignalR代理在网页,通过生成的Js来完成相关的功能.但我不禁想一个问题, 难到SignalR的服务端就能寄存在web端吗,通过访问网页能方式才能启动 ...
- Redis入门很简单之二【常见操作命令】
Redis入门很简单之二[常见操作命令] 博客分类: NoSQL/Redis/MongoDB redisnosql缓存 Redis提供了丰富的命令,允许我们连接客户端对其进行直接操作.这里简单介绍一 ...
- Java-Springboot-集成spring-security简单示例(Version-springboot-2-1-3-RELEASE
使用Idea的Spring Initializr或者SpringBoot官网下载quickstart 添加依赖 1234 <dependency><groupId>org.sp ...
随机推荐
- 微信公众号支付(三):页面调用微信支付JS并完成支付
一.调用微信的JS文件 1.首先要绑定[JS接口安全域名],“公众号设置”的“功能设置”中 2.引入JS文件 备注:支持使用 AMD/CMD 标准模块加载方法加载 <script type=&q ...
- Java 字节数组类型(byte[])与int类型互转
代码如下: public class CommonUtils { //高位在前,低位在后 public static byte[] int2bytes(int num){ byte[] result ...
- 【腾讯Bugly干货分享】总结一个技术总监的教训和经验
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/Ry-G0Nikh6m-h3ZVC2cLyQ 导语 20 ...
- Eval()和DataBinder Eval(Container DataItem,)的区别及用法
ASP.NET 2.0改善了模板中的数据绑定操作把v1.x中的数据绑定语法DataBinder.Eval(Container.DataItem, fieldname)简化为Eval(fiel ...
- 实现方法 C# button快捷键
本文讲解了三种方法实现C# button快捷键,如Alt + *(按钮快捷键),Ctrl+*及其他组合键等. C# button快捷键之第一种:Alt + *(按钮快捷键) 在大家给button.la ...
- 状态栏通知Notification的简单使用
今天在学习Notification时同时参考了一些相关的博客,现在结合自身学习实际来总结一下. 在使用手机时,当有未接来电或者短消息时,通常会在手机屏幕上的状态栏上显示.而在Android中有提醒功能 ...
- 保留关键字 (Transact-SQL)
https://msdn.microsoft.com/zh-cn/library/ms189822(v=sql.120).aspx Microsoft SQL Server 将保留关键字用于定义.操作 ...
- 堆排序算法(C#实现)
在软件设计相关领域,“堆(Heap)”的概念主要涉及到两个方面: 一种是数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆). 另一种是垃圾收集存储区,是软件系统可以编程的内存区域. 本文 ...
- 访问权限PPP(public、private、protected、default)之成员变量、成员变量权限解析
首先,我们需要清楚一下方法是由哪些部分构成的: [权限修饰符列表][别的修饰符列表] 返回值类型 方法名(参数列表){ 方法体:} 然后我们需要知道成员变量和成员方法访问有几种情况:1.当前包同一 ...
- swift-03-数据类型转换
// main.swift // 05-数据类型的转换 // // Created by wanghy on 15/8/9. // Copyright (c) 2015年 wanghy. Al ...