spring-security用户权限认证框架

      你们知道在spring中有一个基于acegi开发的spring-security的权限管理模块,它是一个轻量级框架。 SpringSecurity能以声明的方式来保护Web应用程序的URL访问,只需简单的配置便可实现。SpringSecurity经过一系列Servlet过滤器为Web应用程序提供了多种安全服务。
      配置spring-security
     在web.xml中添加过滤器:html

<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>

   而后在<classpath>路径下建立配置文件PROJECT-security.xml:web

<?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-2.0.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security-2.0.xsd">

    <http auto-config="true" access-denied-page="/access_denied.jsp">
        <intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
        <intercept-url pattern="/user/**" access="ROLE_USER" />

        <form-login login-page="/login.htm" authentication-failure-url="/login.htm?error=1" default-target-url="/" />
        <remember-me data-source-ref="dataSource" />
        <logout invalidate-session="true" logout-success-url="/" />
        <!--
        Uncomment to enable X509 client authentication support
        <x509 />
          -->
    </http>

    <authentication-provider>
        <!--
        <password-encoder hash="md5" />
          -->
        <jdbc-user-service data-source-ref="dataSource"
            users-by-username-query="select account as username, password, status as enabled from user where account=?"
            authorities-by-username-query="select account as username, authority from user where account=?" />
    </authentication-provider>
</beans:beans>

同时将该配置文件加到web.xml的 <context-param> 里。spring

spring-security中使用角色来分类管理用户权限,如上面的配置中就包含了ROLE_ADMIN和ROLE_USER两个角色,并分别有/admin/和/user/的URL路径下的权限。数据库

在数据库中保存用户

用户的账号密码有几种不一样的方式保存,包括xml中、LDAP和数据库中等。上面使用的是保存到数据库中的方式,使用了以前在applicationContext.xml中配置的dataSource bean。使用数据库保存账号时,须要按照spring-security规定的字段来建表,有两个相关的表,分别用于保存账号密码和登陆状态。使用MySQL能够这样建立:安全

CREATE TABLE `user` (
  `account` varchar(50) NOT NULL,
  `password` varchar(50) NOT NULL,
  `authority` varchar(50) NOT NULL,
  `status` tinyint(1) NOT NULL,
  UNIQUE KEY `account` (`account`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

加密密码

默认spring-security中采用明文方式存储密码,能够经过设置 <password-encoder> 来对密码加密。这时对应的用户注册模块也要将密码以加密后的数据保存到数据库中才行。session

import org.springframework.security.providers.encoding.Md5PasswordEncoder;
import org.springframework.security.providers.encoding.PasswordEncoder;

PasswordEncoder encoder = new Md5PasswordEncoder();
String password = encoder.encodePassword(form.getPassword(), null);

阻止用户重复登录

能够经过会话控制来防止用户重复登陆,这能够经过配置来实现。首先在web.xml中添加监听:app

<listener>
    <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>
</listener>

而后在PROJECT-security.xml配置文件中的 <http></http> 内添加:框架

<concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true" />

max-sessions="1" 表示该用户同时登陆的最大会话数为1, exception-if-maximum-exceeded="true" 表示阻止超出的用户登陆。jsp

在jsp中加入spring-security

spring-security给出了在jsp中使用的接口。用户登陆能够使用下面的表单:ide

<form name='f' action='/PROJECT/j_spring_security_check' method='POST'>
<table>
  <tr><td>用户名:</td><td><input type='text' name='j_username' value=''></td></tr>
  <tr><td>密码:</td><td><input type='password' name='j_password'/></td></tr>
  <tr><td></td><td><input type='checkbox' name='_spring_security_remember_me'/> 自动登陆</td></tr>
  <tr><td colspan='2' align="right"><input name="reset" id="reset" type="reset" value="重置" /> <input name="submit" id="submit" type="submit" value="登陆" /></td></tr>
</table>
</form>

根据登陆用户进行条件判断能够使用下面的方式:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<sec:authorize ifAllGranted="ROLE_ANONYMOUS">
<!-- ... -->
</sec:authorize>
<sec:authorize ifAllGranted="ROLE_USER">
<!-- ... -->
</sec:authorize>

在特定jsp页面获取登陆用户的账号的方法是:

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>

<input name="customer" type="hidden" value="<sec:authentication property='principal.username' />" />

另外, Spring Security 还提供了以下一些功能:

1.       remember me ,记住我;

2.       form-login 登陆控制;

3.       多种身份认证功能;

4.       用户密码加密和“ salt ”功能;

5.       http 协议控制;

6.       访问端口控制;

7.       Pre-Invocation & After-Invocation 。

spring-security还有不少相关的用法,能够查看 官方的文档 。 http://www.yeolar.com/note/2011/10/19/spring-security/