1. 程式人生 > >SpringMVC+Spring Security實現登入認證的簡單功能

SpringMVC+Spring Security實現登入認證的簡單功能

一、依賴pom.xml

這裡僅僅列出security需要的依賴,其他依賴見前面Spring目錄下文章。

<!-- Spring Security -->
     <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-core</artifactId>
         <version>3.1.4.RELEASE</version>
     </dependency>
     <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-web</artifactId>
         <version>3.1.4.RELEASE</version>
     </dependency>
     <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-config</artifactId>
         <version>3.1.4.RELEASE</version>
     </dependency>
     <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-taglibs</artifactId>
         <version>3.1.4.RELEASE</version>
     </dependency>

二、web.xml配置

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >


<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <!-- 字元編碼過濾器 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <!-- 配置專案的編碼mapping -->
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 配置spring security 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>/ps_service/*</url-pattern>
    </filter-mapping>
    <!-- 指定spring security配置檔案的位置 -->
    <context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/config/spring-security.xml</param-value>
    </context-param>
    <!-- 開啟spring功能 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- request監聽 -->
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>


    <!-- session監聽-->
    <listener>
        <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
    </listener>
    <!-- Spring MVC 基本配置 -->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/springMVC-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup><!-- 標記容器是否在啟動的時候就載入這個servlet,1代表優先順序 -->
    </servlet>


    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>ps_service/*</url-pattern><!-- 注意這裡就是URL攔截配置 -->
    </servlet-mapping>
    
    <!-- session超時 17061434 -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

三、springMVC-servlet.xml主要用來進行檢視解析以及掃描controller

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation=
       "http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
        http://www.springframework.org/schema/context  
        http://www.springframework.org/schema/context/spring-context-3.1.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
        
    <context:component-scan base-package="com.suning.service"/>
    <context:component-scan base-package="com.suning.viewsolver"/>
    <context:component-scan base-package="com.suning.web"/>
    <context:component-scan base-package="com.suning.web.authority"/>
    <!-- 註解 @Controller 對映的支援 -->
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
    <bean id="httpRequestHandlerAdapter" class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
        
    <!-- freeMarker檢視解析 17061434 -->
    <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="prefix" value=""/>
        <property name="suffix" value=""/>
        <property name="order" value="2"/>
        <property name="viewNames" value="*.ftl"/>
        <property name="contentType" value="text/html;charset=utf-8"/>
    </bean>
    <!-- ftl配置 17061434-->
    <bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="defaultEncoding" value="UTF-8"/>
        <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
    </bean>


    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="order" value="1"/>
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json"/>
                <entry key="jsonp" value="application/javascript"/>
            </map>
        </property>
        <property name="viewResolvers">
            <list>
                <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
                <ref bean="freeMarkerViewResolver"/> 
                <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/> 
            </list>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
                </bean>
                <bean class="com.suning.viewsolver.JsonpView"/>
            </list>
        </property>
        <property name="ignoreAcceptHeader" value="true"/>
    </bean>
    <!-- Redis和 Hbase的外部配置檔案進行統一載入-->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
        <property name="fileEncoding" value="UTF-8" />   
        <property name="locations">  
            <list>  
                <value>file:/opt/search/resourse/hbase.properties</value> 
                <value>file:/opt/search/resourse/ps_redis.properties</value> 
            </list>  
        </property>  
    </bean>  
    <!-- Redis配置 -->
    <import resource="/redis.xml" /> 
    <!-- Hbase配置 -->
    <import resource="/spring-hbase.xml" />
</beans>

四、spring-security.xml主要用來進行攔截認證

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security 
                    http://www.springframework.org/schema/security/spring-security-3.1.xsd">


    <security:http use-expressions="true">
        <!-- 順序不能亂 ,按照從上往下依次過濾 -->
        <!-- 預設不過濾的url(不需要登入) -->
        <security:intercept-url pattern="/ps_service/index.jsp" access="permitAll"/>
        <security:intercept-url pattern="/ps_service/login.do" access="permitAll"/>
        <security:intercept-url pattern="/ps_service/loginfailed.do" access="permitAll"/>
        <!--<security:intercept-url pattern="/cs/404.html" access="permitAll"/>-->
        <!--<security:intercept-url pattern="/favicon.ico" access="permitAll"/>--><!--過濾瀏覽器自動發起的連結-->


        <!-- 除/admin/*(web.xml中)和permitAll外,任何url都要攔截 -->
        <security:intercept-url pattern="/**" access="authenticated"/>


        <!-- 登入認證 -->
        <security:form-login login-page="/ps_service/login.do"
                             authentication-failure-url="/ps_service/loginfailed.do"
                             username-parameter="sescs_username"
                             password-parameter="sescs_password"
                             default-target-url="/"
                             always-use-default-target="false"/>
        <!--暫且遮蔽後面角色分配用<security:custom-filter after="FILTER_SECURITY_INTERCEPTOR" ref="filterUrl"/>-->
        <!-- logout-success-url:成功登出後跳轉到的頁面; -->
        <security:logout logout-url="/ps_service/j_spring_security_logout" logout-success-url="/ps_service/login.do"/>
        <!-- session管理,invalid-session-url重定向,指定使用已經超時的sessionId進行請求需要重定向的頁面-->
        <security:session-management invalid-session-url="/ps_service/login.do"/>
    </security:http>


    <!-- 啟用註解 -->
    <security:global-method-security pre-post-annotations="enabled"/>
    
    <!-- 安全認證管理,先寫個簡單的後面再改-->
    
    <security:authentication-manager>
         <security:authentication-provider>
             <security:user-service>
                 <security:user name="admin" password="123456" authorities="ROLE_USER"/><!--設定登入的使用者名稱和密碼-->
             </security:user-service>
         </security:authentication-provider>
    </security:authentication-manager>
    
    <!-- 安全認證管理,這裡用了資料庫,後面再用 -->
    <!--<security:authentication-manager>
        <security:authentication-provider ref="filterLogin"/>
    </security:authentication-manager>


    <bean id="filterLogin" class="com.suning.search.admin.web.controller.authority.FilterLogin"/>


    <bean id="filterUrl" class="com.suning.search.admin.web.controller.authority.FilterUrl"/>-->
</beans>

五、controller類:

@RequestMapping("/index.html")
private String gIndex() {
    return "redirect:/ps_service/index.do";
}
@RequestMapping("/index.do")
public String index(ModelMap modelMap, HttpServletRequest request) {
       return "/admin/hello.ftl";
}

@RequestMapping("login.do")
    public String login(ModelMap modelMap, HttpServletRequest request) {//登入
        return "admin/login.ftl";
    }
@RequestMapping("loginfailed.do")
    public String loginError(ModelMap model) {//登入失敗
        model.addAttribute("error", "true");
        return "admin/login.ftl";
    }

六、登入首頁login.ftl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title> Ps System</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <!-- Favicons -->
    <link rel="shortcut icon" href="/static/images/icons/favicon.ico">
    <!-- HELPERS -->
    <link rel="stylesheet" type="text/css" href="/static/helpers/helpers-all.css">
    <!-- ELEMENTS -->
    <link rel="stylesheet" type="text/css" href="/static/elements/elements-all.css">
    <!-- Icons -->
    <link rel="stylesheet" type="text/css" href="/static/icons/fontawesome/fontawesome.css">
    <!-- Admin Theme -->
    <link rel="stylesheet" type="text/css" href="/static/themes/supina/layout.css">
    <link id="layout-color" rel="stylesheet" type="text/css" href="/static/themes/supina/default/layout-color.css">
    <link id="framework-color" rel="stylesheet" type="text/css"
          href="/static/themes/supina/default/framework-color.css">
    <link rel="stylesheet" type="text/css" href="/static/themes/supina/border-radius.css">
    <!-- Color Helpers CSS -->
    <link rel="stylesheet" type="text/css" href="/static/helpers/colors.css">
    <!-- JS Core -->
    <script type="text/javascript" src="/static/js-core.js"></script>


    <style>
        #loading {
            position: fixed;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            display: block;
            background: #fff;
            z-index: 10000;
        }


        #loading img {
            position: absolute;
            top: 50%;
            left: 50%;
            margin: -23px 0 0 -23px;
        }
    </style>


    <script type="text/javascript">
        $(window).load(function () {
            setTimeout(function () {
                $('#loading').fadeOut(10, "linear");
            }, 50);
        });


        function admin_submit() {


            $("#login_form")[0].submit();


        }
    </script>


</head>
<body>
<div id="loading"><img src="/static/images/spinner/loader-dark.gif" alt="Loading..."></div>


<div class="center-vertical" style="background-image: url(/static/images/book.jpg)">
    <div class="center-content">
        <form name="login_form" id="login_form" action="/ps_service/j_spring_security_check" class="col-md-4 center-margin"
              method="post" onsubmit="return false">
            <h3 class="text-center pad25B font-white text-transform-upr font-size-30">歡迎來到PS系統<span
                    class="opacity-80">v1.0</span></h3>


            <div id="login-form" class="content-box modal-content">
                <div class="content-box-wrapper pad20A">
                    <div class="form-group">
                        <label for="username">User Name:</label>


                        <div class="input-group input-group-lg">
                                <span class="input-group-addon addon-inside bg-white font-primary">
                                    <i class="glyph-icon icon-envelope-o"></i>
                                </span>
                            <input name="sescs_username" id="sescs_username" type="text" class="form-control"
                                   placeholder="輸入使用者名稱">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="password">Password:</label>


                        <div class="input-group input-group-lg">
                                <span class="input-group-addon addon-inside bg-white font-primary">
                                    <i class="glyph-icon icon-unlock-alt"></i>
                                </span>
                            <input name="sescs_password" id="sescs_password" type="password" class="form-control"
                                   placeholder="輸入密碼">
                        </div>
                    </div>
                </div>
                <div class="button-pane">
                    <button type="submit" class="btn btn-block btn-primary" onclick="admin_submit()">Login</button>
                </div>
            </div>
        </form>


    </div>
</div>


</body>
</html>

七、登入後展示頁面hello.ftl

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   
 "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
        <title>Spring MVC And Freemarker</title>  
    </head>  
    <body>  
         Hello world , test my first spring mvc !  
    </body>  
</html>