[Spring实战系列] - No.10 Spring Security基于XML的简单登录例子

这篇文章开始,我们会进入Spring Security部分。大概会有三到四篇文章来介绍Security部分,在这篇文章中,我们会使用XML配置的方式来配置一个简单的Spring Security登录的例子,感受一下什么是Spring Security,我们怎么使用Spring Security。

1. 什么是Spring Security?

Spring Security是为基于Spring的应用程序提供声明式安全保护的安全性框架。Spring Security提供了完整的安全性解决方案,它能够在Web请求级别和方法调用级别处理身份认证和授权。什么叫Web请求级别和方法调用级别呢?就会当我们通过Controller发送一个请求或者我们的DispatcherSevlet接受到一个请求的时候,我们使用Spring Security 事先声明好的filter,来拦截所有的请求,判断用户是否有权访问该资源。所以,我们会在Spring Security中用到依赖注入和切面编程(AspectJ)的技术。

Spring Security借助一系列Servlet Filter来提供各种安全性功能。我们只需在web.xml配置一个Filter就可以了。DelegatingFilterProxy是一个特殊的Servlet Filter,它本身所做的工作并不多。只是将工作委托给一个javax.servlet.Filter实现类,这个实现类作为一个<bean>注册在Spring应用的上下文中


2. 一个简单的Spring Security登录例子:

首先我们新建Maven项目,过程和前面文章相同,新建后的项目结构如下:


完善你的pom.xml中的依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>SpringSecurity</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SpringSecurity Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
      <!-- ... other dependency elements ... -->
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>4.0.4.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>4.1.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>4.0.3.RELEASE</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>


  </dependencies>
  <build>
    <finalName>SpringSecurity</finalName>
  </build>
</project>

作为Spring项目,首先就要有一个DispatcherServlet对吧?配置你的DispatcherServlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <context:component-scan base-package="Hello" />

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>
我们将Spring Security的配置均放在security.xml中:

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

    <http auto-config="true">
        <intercept-url pattern="/admin**" access="hasRole('ROLE_USER')" />
        <logout logout-url="/logout" logout-success-url="/logoutPage" invalidate-session="true"/>
        <csrf disabled="true" />
    </http>

    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="yanming" password="123" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>

</beans:beans>
我们来解释一下这段代码:

1.http auto-config:默认的策略进行访问控制,包括一个默认的访问登录界面(我们在这个项目中并没有提供登陆的界面,稍后会说到)

2.authentication-manager:认证管理器负责确定用户的身份,认证管理器由AuthenticationManager接口定义,这里我们就用了缓存的用户信息
3.intercept-url pattern :通过pattern指定当前intercept-url定义应当作用于哪些url。

4.logout:匹配我们退出登录的url 在我们的Spring Security4.x中,我们需要关闭csrf才能够使用/logout。

web.xml中配置filter以及servlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
         version="3.0">

  <display-name>Spring MVC Application</display-name>

  <!-- Spring MVC -->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <!--Sources标注的文件夹下需要新建一个spring文件夹-->
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/DispatcherServlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>


  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>

  <!-- Loads Spring Security config file -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
      /WEB-INF/security.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>

</web-app>
在Hello包中定义HelloController:

package Hello;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by YanMing on 2017/3/15.
 */
@Controller
public class HelloController {
    @RequestMapping(value = {"/" ,"/welcome"},method = RequestMethod.GET)
    public ModelAndView homePage(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("title","Hello world");
        modelAndView.setViewName("home");
        return modelAndView;
    }

    @RequestMapping(value = {"/logoutPage"},method = RequestMethod.GET)
    public ModelAndView logoutPage(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("logout");
        return modelAndView;
    }

    @RequestMapping(value = "/admin",method = RequestMethod.GET)
    public ModelAndView adminPage(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("title","Please log in");
        modelAndView.setViewName("admin");
        return modelAndView;
    }
}
三个映射很简单,返回三个modelandview对象,匹配对应url同时返回相应的jsp文件。

在WEB-INF中定义jsp文件:

admin.jsp:

<%--
  Created by IntelliJ IDEA.
  User: YanMing
  Date: 2017/3/14
  Time: 21:31
  To change this template use File | Settings | File Templates.
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<body>
<h1>Title:${title}</h1>

<c:if test="${pageContext.request.userPrincipal.name != null}">
    <h2>Welcome:${pageContext.request.userPrincipal.name}
        |<a href="<c:url value="/logout" />" > Logout</a></h2>
</c:if>
</body>
</html>
home.jsp:

<%--
  Created by IntelliJ IDEA.
  User: YanMing
  Date: 2017/3/15
  Time: 14:51
  To change this template use File | Settings | File Templates.
--%>
<%@page session="false"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<h1>Title:${title}</h1>
<a href="<c:url value="/admin" />" >Login</a></h2>
</body>
</html>
logout.jsp(对应退出成功以后的页面):

<%--
  Created by IntelliJ IDEA.
  User: YanMing
  Date: 2017/3/15
  Time: 15:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <h1>Logout Successfully!</h1>
</head>
<body>

</body>
</html>

配置Tomcat,不会配置的同学点击之前文章

然后在页面中输入localhost:8080

点击Login:

输入 yaming 123 登录

点击Logout


至此,一个简单的Spring Security的登录例子就写完了。在下一篇文章中,我们会开始使用数据库来存储我们的用户名密码。所以,我会重新使用Java 来配置Spring Security。不过,xml的配置过程显得很清晰,理解起来也很简单。同时下篇文章我也会详细的讲解Spring Security的核心部分以及具体过程。


本文Github源码下载


P.S. 文章不妥之处还望指正










  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值