使用Spring Security实现权限管理

了解并创建Security框架所需数据表
为项目添加Spring Security框架
掌握Security框架配置
应用Security框架为项目操作绑定权限

SET FOREIGN_KEY_CHECKS=0;  
    ------------------------------  
    -- 创建管理员帐号表t_admin  
    -- ----------------------------  
    CREATE TABLE `t_admin` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `passwd` varchar(12) NOT NULL DEFAULT '' COMMENT '密码',  
      `nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '名字',  
      `phoneno` varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',  
      PRIMARY KEY (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;  

    -- ----------------------------  
    -- 添加管理账户 
    -- ----------------------------  
    INSERT INTO `t_admin` VALUES ('1', 'admin', 'admin', '');  
    INSERT INTO `t_admin` VALUES ('4', '123456', 'test', '');  
    INSERT INTO `t_admin` VALUES ('5', '111111', '111111', '');  

    -- ----------------------------  
    -- 权限表 
    -- ----------------------------  
    CREATE TABLE `t_role` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `role` varchar(40) NOT NULL DEFAULT '',  
      `descpt` varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',  
      `category` varchar(40) NOT NULL DEFAULT '' COMMENT '分类',  
      PRIMARY KEY (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8;  

    -- ----------------------------  
    -- 操作权限  
    -- ----------------------------  
    INSERT INTO `t_role` VALUES ('1', 'ROLE_ADMIN', '系统管理员', '系统管理员');  
    INSERT INTO `t_role` VALUES ('2', 'ROLE_UPDATE_FILM', '修改', '影片管理');  
    INSERT INTO `t_role` VALUES ('3', 'ROLE_DELETE_FILM', '删除', '影片管理');  
    INSERT INTO `t_role` VALUES ('4', 'ROLE_ADD_FILM', '添加', '影片管理');  

    -- ----------------------------  
    -- 创建权限组表  
    -- ----------------------------  
    CREATE TABLE `t_group` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `groupname` varchar(50) NOT NULL DEFAULT '',  
      PRIMARY KEY (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;  

    -- ----------------------------  
    -- 添加2个权限组  
    -- ----------------------------  
    INSERT INTO `t_group` VALUES ('1', 'Administrator');  
    INSERT INTO `t_group` VALUES ('2', '影片维护');  

    -- ----------------------------  
    -- 创建权限组对应权限表t_group_role  
    -- ----------------------------  
    CREATE TABLE `t_group_role` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `groupid` bigint(20) unsigned NOT NULL,  
      `roleid` bigint(20) unsigned NOT NULL,  
      PRIMARY KEY (`id`),  
      UNIQUE KEY `groupid2` (`groupid`,`roleid`),  
      KEY `roleid` (`roleid`),  
      CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  
      CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8;  

    -- ----------------------------  
    -- 加入权限组与权限的对应关系  
    -- ----------------------------  
    INSERT INTO `t_group_role` VALUES ('1', '1', '1');  
    INSERT INTO `t_group_role` VALUES ('2', '2', '2');  
    INSERT INTO `t_group_role` VALUES ('4', '2', '4');  

    -- ----------------------------  
    -- 创建管理员所属权限组表t_group_user  
    -- ----------------------------  
    CREATE TABLE `t_group_user` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `userid` bigint(20) unsigned NOT NULL,  
      `groupid` bigint(20) unsigned NOT NULL,  
      PRIMARY KEY (`id`),  
      KEY `userid` (`userid`),  
      KEY `groupid` (`groupid`),  
      CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),  
      CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;  

    -- ----------------------------  
    -- 将管理员加入权限组  
    -- ----------------------------  
    INSERT INTO `t_group_user` VALUES ('1', '1', '1');  
    INSERT INTO `t_group_user` VALUES ('2', '4', '2');  

    -- ----------------------------  
    -- 创建管理员对应权限表t_user_role  
    -- 设置该表可跳过权限组,为管理员直接分配权限  
    -- ----------------------------  
    CREATE TABLE `t_user_role` (  
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
      `userid` bigint(20) unsigned NOT NULL,  
      `roleid` bigint(20) unsigned NOT NULL,  
      PRIMARY KEY (`id`),  
      KEY `userid` (`userid`),  
      KEY `roleid` (`roleid`),  
      CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),  
      CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)  
    ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;  

在项目中新增如下jar包(security框架所需jar包):

创建,放置登录验证过滤器代码:

在src下创建Spring配置文件applicationContext-security.xml,内容如下:


<?xml version="1.0" encoding="UTF-8"?>  

    <beans:beans xmlns="http://www.springframework.org/schema/security"  
        xmlns:b="http://www.springframework.org/schema/beans" 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.1.xsd">  



</beans:beans>  

3.5)在web.xml中加入security配置,如下:

<?xml version="1.0" encoding="UTF-8"?>  
    <web-app version="2.5"   
        xmlns="http://java.sun.com/xml/ns/javaee"   
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
      <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
      </welcome-file-list>  

        <context-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml</param-value>  
        </context-param>  

        <!-- 配置Spring Security -->  
        <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>  

        <filter>  
            <filter-name>struts2</filter-name>  
            <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
        </filter>  
        <filter-mapping>  
            <filter-name>struts2</filter-name>  
            <url-pattern>/*</url-pattern>  
        </filter-mapping>  
        <listener>  
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
        </listener>  
    </web-app>  

4、创建登录页面login.jsp,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"  
    pageEncoding="UTF-8"%>  
<%@ taglib prefix="s" uri="/struts-tags"%>  
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
<%   
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;   
%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<title>后台登录</title>  
</head>  
<body onload="document.loginForm.j_username.focus();">  
    <!-- 登录表单 -->  
    <form name="loginForm" action="<c:url value='/j_spring_security_check'/>" method="post">  
        <!-- 登录失败后,显示之前的登录名 -->  
        用户名:<input type='text' name='j_username' class="txtinput"  
        value='<c:if test="${not empty param.login_error}" >  
        <c:out value="${SPRING_SECURITY_LAST_USERNAME}"/></c:if>' />  
        <br />  
        密码:<input type='password' name='j_password' class="txtinput" />  
        <br />  

        <input type="checkbox" name="_spring_security_remember_me" />  
        &nbsp;保存登录信息  
        <input name="submit" type="submit" value="提交" />  
        <input name="reset" type="reset" value="重置" />  

    </form>  
    <br />  
    <!-- 显示登录失败原因 -->  
    <c:if test="${not empty param.error}">  
        <font color="red"> 登录失败<br />  
        <br />  
        原因: <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />. </font>  
    </c:if>  
</body>  
</html>  

<%@page session="false" %>  
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
<%@ page pageEncoding="UTF-8"%>  
<%   
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;   
%>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
  <head>  
      <meta http-equiv="content-type" content="text/html; charset=UTF-8" />  
      <title>登出</title>  
  </head>  
<body>  
你已经退出。   
<a href="<c:url value='/login.jsp'/>">点击这里登录</a>  
</body>  
</html>  

7、创建登录验证过滤器,该过滤器可用于在管理员登录时进行日志记录等相关操作,包括两个类:

public class LoginUsernamePasswordAuthenticationFilter extends  
        UsernamePasswordAuthenticationFilter {  

}  

LoginSuccessHandler类

```
package com.xxx.security;  

import java.io.IOException;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.springframework.security.core.Authentication;  
import org.springframework.security.core.userdetails.UserDetails;  
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;  

/** 
 * 处理管理员登录日志 
 * 
 */  
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{  

    @Override  
    public void onAuthenticationSuccess(HttpServletRequest request,  
            HttpServletResponse response, Authentication authentication) throws IOException,  
            ServletException {  

        UserDetails userDetails = (UserDetails)authentication.getPrincipal();  

        //输出登录提示信息  
        System.out.println("管理员 " + userDetails.getUsername() + " 登录");  

        super.onAuthenticationSuccess(request, response, authentication);  
    }  

}  

加入权限

<?xml version="1.0" encoding="UTF-8"?>  

<beans:beans xmlns="http://www.springframework.org/schema/security"  
    xmlns:b="http://www.springframework.org/schema/beans" 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.1.xsd">  

    <http >  
        <!-- 不拦截login.jsp -->  
        <intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" />  
        <!--仅拦截到manager下面的内容,具备access对应权限的-->  
        <intercept-url pattern="/manager/**" access="ROLE_ADMIN,ROLE_UPDATE_FILM,ROLE_DELETE_FILM,ROLE_ADD_FILM" />  
        <!-- 设置登录过滤器 -->  
        <custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" />  
        <!-- 登录表单设置 -->  
        <form-login login-page="/login.jsp"  
            default-target-url="/manager/films.jsp"  
            authentication-failure-url="/login.jsp?error=true" />  

        <!-- 登出操作后跳转到该页面 -->  
        <logout logout-success-url="/loggedout.jsp"  
            delete-cookies="JSESSIONID" />  
        <remember-me />  

        <!-- SESSION超时后跳转到该页面 -->  
        <session-management invalid-session-url="/timeout.jsp">  
        </session-management>  
    </http>  

    <authentication-manager alias="authenticationManager">  
        <authentication-provider>  
            <!--   
                直接使用SQL语句查询登录帐号对应权限,  
                users-by-username-query:查询登录用户是否存在  
                authorities-by-username-query:查询登录用户权限(登录用户可以不属于任何组,从t_user_role表中获取权限)  
                group-authorities-by-username-query:查询登录用户所在组的权限  
            -->  
            <jdbc-user-service data-source-ref="dataSource"  
            group-authorities-by-username-query="SELECT g.id,g.groupname,role.role  
                             FROM t_group AS g   
                             LEFT OUTER JOIN t_group_role AS grouprole ON (g.id = grouprole.groupid)  
                             LEFT OUTER JOIN t_role AS role ON (role.id = grouprole.roleid)  
                             LEFT OUTER JOIN t_group_user AS groupuser on (g.id = groupuser.groupid)  
                             LEFT OUTER JOIN t_admin ON (t_admin.id = groupuser.userid)  
                             WHERE t_admin.nickname = ?"  
                users-by-username-query="SELECT t_admin.nickname AS username,t_admin.passwd as password,'true' AS enabled  
                             FROM t_admin  
                             WHERE t_admin.nickname = ?"  
                authorities-by-username-query="SELECT t_admin.nickname AS username,role.role as authorities  
                               FROM t_admin   
                               LEFT OUTER JOIN t_user_role AS userrole ON(t_admin.id = userrole.userid)  
                               LEFT OUTER JOIN t_role AS role ON (userrole.roleid = role.id)  
                               WHERE t_admin.nickname = ?" />  
        </authentication-provider>  
    </authentication-manager>  

    <!-- 自定义消息 -->  
    <b:bean id="messageSource"  
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
        <b:property name="basename"  
            value="classpath:org/springframework/security/messages" />  
    </b:bean>  

    <!-- 定制登录过滤器 -->  
    <beans:bean id="loginSuccessHandler" class="com.xxx.security.LoginSuccessHandler">  
        <b:property name="defaultTargetUrl">  
            <!-- 登录成功后转发到该页面 -->  
            <b:value>/manager/films.jsp</b:value>  
        </b:property>  
    </beans:bean>  
    <beans:bean id="authenticationProcessingFilter" class="com.xxx.security.LoginUsernamePasswordAuthenticationFilter">    
    <beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"></beans:property>    
    <beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"></beans:property>    
    <beans:property name="authenticationManager" ref="authenticationManager"></beans:property>    
    </beans:bean>  
    <beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">    
    <beans:property name="defaultFailureUrl">  
        <!-- 登录失败后转发到该页面 -->  
        <beans:value>/login.jsp?error=true</beans:value>    
    </beans:property>  
    </beans:bean>  

</beans:beans>  

films.jsp

```
<%@ page language="java" contentType="text/html; charset=utf-8"  
pageEncoding="utf-8" %>  
<%@taglib uri="/struts-tags" prefix="s" %>  
<%@ 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">  
<html>  
  <head>  
    <title>信息操作</title>  
  </head>  
  <body>  
    <s:form action="/film/findFilm" method="post">  
        <s:submit value=" 获取所有影片信息 "></s:submit>  
    </s:form>  
 <!-- 添加影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_ADD_FILM权限可以执行 -->  
    <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_ADD_FILM">  
    <a href="<%=basePath %>manager/insertFilm.jsp">添加影片信息</a><br />   
    </security:authorize>  

    <s:if test="filmList != null">  
        <table border="1" width="40%">  
    <tr>  
        <th>序号</th><th>影片名</th><th>操作</th>  
    </tr>   
        <%-- 遍历影片信息 --%>  
        <s:iterator var="film" value="filmList" status="st">  
            <tr>  
                <td><s:property value="#st.index+1" /></td>  
                <td><s:property value="fname" /></td>  
                <td>  

                    <!-- 修改影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_UPDATE_FILM权限可以执行 -->  
                    <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_UPDATE_FILM">  
                        <s:url id="detailUrl" value="/film/detailFilm">  
                                    <s:param name="id" value="%{id}"/>  
                                    </s:url>  
                        <s:a href="%{detailUrl}">[修改]</s:a>&nbsp;  
                    </security:authorize>  
                    <!-- 删除影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_DELETE_FILM权限可以执行 -->  
                    <security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_DELETE_FILM">  
                        <s:url id="deleteUrl" value="/film/deleteFilm">  
                                    <s:param name="id" value="%{id}"/>  
                                    </s:url>  
                        <s:a href="%{deleteUrl}">[删除]</s:a>  
                    </security:authorize>  
            </td>  
            </tr>  
        </s:iterator>  
    </table>  
    </s:if>  
  </body>  
</html>  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值