zoukankan      html  css  js  c++  java
  • Spring Security 入门

    一、Spring Security简介

      Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

      Spring security主要是从两个方面解决安全性问题:

    1. web请求级别:使用servlet过滤器保护web请求并限制URL级别的访问
    2. 方法调用级别:使用Spring AOP保护方法调用,确保具有适当权限的用户采用访问安全保护的方法.

    二、入门小案例

    2.1 使用系统默认的登录页

      (1)创建工程spring-security-demo。pom.xml的内容为:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>cn.itcast</groupId>
      <artifactId>spring-security-demo</artifactId>
      <version>1.0-SNAPSHOT</version>
      <packaging>war</packaging>
    
      <properties>
        <spring.version>4.2.4.RELEASE</spring.version>
      </properties>
      <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-core</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context-support</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-web</artifactId>
          <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework.security</groupId>
          <artifactId>spring-security-config</artifactId>
          <version>4.1.0.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>
      <build>
        <plugins>
          <!-- java编译插件 -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
              <source>1.7</source>
              <target>1.7</target>
              <encoding>UTF-8</encoding>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <configuration>
              <!-- 指定端口 -->
              <port>9090</port>
              <!-- 请求路径 -->
              <path>/</path>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </project>

      (2)创建web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns="http://java.sun.com/xml/ns/javaee"
             xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
             version="2.5">
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-security.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <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>

      (3)创建index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>spring security demo</title>
    </head>
    <body>
        这时spring security的一个小案例
    </body>
    </html>

      (4)创建spring 配置文件spring-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.xsd
                            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
        <!-- 页面拦截规则,use-expressions:是否启动SPEL表达式 默认是true -->
        <http use-expressions="false">
            <!-- 当前用户必须有ROLE_USER的角色 才可以访问根目录及所属子目录的资源
                    /*  表示的是该目录下的资源,只包括本级目录不包括下级目录
                    /** 表示的是该目录以及该目录下所有级别子目录的资源
            -->
            <intercept-url pattern="/**" access="ROLE_USER" />
            <!--开启表单登陆-->
            <form-login/>
        </http>
    
        <!-- 认证管理器 -->
        <authentication-manager>
            <authentication-provider>
                <user-service>
                    <user name="admin" password="123456" authorities="ROLE_USER"/>
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </beans:beans>

      注意:use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,如果开启,则拦截的配置应该写成以下形式

    <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

      此案例我们没有登录页,而是使用了系统自动生成的登陆页,效果如下:

      

    2.2 用户自定义登录页

      实际开发中,我们不可能使用系统生成的登录页,而是使用我们自己的登录页。

      (1)构建登陆页:login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    <body>
        <form action="/login" method="post">
            用户名:<input type="text" name="username">
            密码:<input type="password" name="password">
            <input type="submit" name="submit" value="登录">
        </form>
    </body>
    </html>

       (2)构建登陆失败页  login_error.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login_error</title>
    </head>
    <body>
        登录失败!
    </body>
    </html>

      (3)修改 spring 配置文件spring-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.xsd
                            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
    
        <!--以下页面不拦截-->
        <http pattern="/login.html" security="none"></http>
        <http pattern="/login_error.html" security="none"></http>
    
        <!-- 页面拦截规则,use-expressions:是否启动SPEL表达式 默认是true -->
        <http use-expressions="false">
            <!-- 当前用户必须有ROLE_USER的角色 才可以访问根目录及所属子目录的资源
                    /*  表示的是该目录下的资源,只包括本级目录不包括下级目录
                    /** 表示的是该目录以及该目录下所有级别子目录的资源
            -->
            <intercept-url pattern="/**" access="ROLE_USER" />
            <!--开启表单登陆-->
            <!--login-page:指定登录页面
                default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。
                authentication-failure-url:指定了身份验证失败时跳转到的页面。
            -->
            <form-login login-page="/login.html" default-target-url="/index.html" authentication-failure-url="/login_error.html"/>
            <!--csrf disabled="true",关闭csrf -->
            <csrf disabled="true"/>
        </http>
    
        <!-- 认证管理器 -->
        <authentication-manager>
            <authentication-provider>
                <user-service>
                    <user name="admin" password="123456" authorities="ROLE_USER"/>
                </user-service>
            </authentication-provider>
        </authentication-manager>
    </beans:beans>

      注意:

      a.如果希望某资源不拦截时,需要设置security="none",比如你自定义了登录页面,如果你没有设置登录页security="none"  ,将会出现以下错误:

      

      b.记得关闭csrf ,如果不加会出现错误

      

      CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

  • 相关阅读:
    mysql架构篇之复制模式
    mysql架构篇之一主从从结构
    mysql架构篇之主从结构
    架构师的成长之路初片~Nginx篇~平滑升级
    架构师之成长之路~ceph~报错集
    架构师的成长之路初片~DNS
    python3.x~安装第三方模块
    架构师的成长之路初片~Ceph-object存储~及ceph常用命令
    架构师的成长之路初片~Ceph-block存储
    C# 多线程 Parallel.ForEach 和 ForEach 效率问题研究及理解
  • 原文地址:https://www.cnblogs.com/yft-javaNotes/p/10546866.html
Copyright © 2011-2022 走看看