欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SpringSecurity

程序员文章站 2022-03-14 20:28:50
...

SpringSecurity

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

通过一个简单的例子来使用一下Spring Security

(1)创建一个基于Maven的javaweb工程spring-security-demo
(2)完善项目结构
(3)在pom.xml文件中导入依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-web</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-config</artifactId>
  <version>5.1.5.RELEASE</version>
</dependency>

(4)配置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>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-security.xml</param-value>
  </context-param>
  <!--SpringSecurity过滤器链  -->
  <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>
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
</web-app>

(5)配置Spring配置文件

<?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.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">
    <!--以下请求不被拦截-->
    <security:http pattern="/login.html" security="none"></security:http>
    <!-- 请求拦截规则 -->
    <!--
        use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,
        如果开启,则拦截的配置应该写成以下形式
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        为false 则拦截的配置应该写成以下形式
        <intercept-url pattern="/**" access="ROLE_USER" />
        intercept-url 表示拦截页面
        /*  表示的是该目录下的资源,只包括本级目录不包括下级目录
        /** 表示的是该目录以及该目录下所有级别子目录的资源
        form-login  为开启表单登陆
    -->
    <security:http use-expressions="false">
        <security:intercept-url pattern="/**" access="ROLE_USER" />
        <!--  form-login设置开启表单登陆
                login-page:指定登录页面
                default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面
                authentication-failure-url:指定了身份验证失败时跳转到的页面。
        -->
        <security:form-login login-page="/login.html"
                             default-target-url="/success.html"
                             authentication-failure-url="/login.html"/>
        <!--关闭csrf-->
        <security:csrf disabled="true"/>
        <!-- 允许iframe -->
        <security:headers>
            <security:frame-options policy="SAMEORIGIN" />
        </security:headers>
        <!--配置退出-->
        <security:logout></security:logout>
    </security:http>
    <!-- 配置认证管理器 -->
    <!-- 固定账号和密码的认证管理器 -->
    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service >
                <security:user name="admin"
                               password="{MD5}e10adc3949ba59abbe56e057f20f883e" authorities="ROLE_USER"/>
                <security:user name="zhangsan"
                               password="{MD5}8ddcff3a80f4189ca1c9d4d902c3c909" authorities="ROLE_USER"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

<?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.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">
    <!--以下请求不被拦截-->
    <security:http pattern="/login.html" security="none"></security:http>
    <!-- 请求拦截规则 -->
    <!--
        use-expressions 为是否使用使用 Spring 表达式语言( SpEL ),默认为true ,
        如果开启,则拦截的配置应该写成以下形式
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        为false 则拦截的配置应该写成以下形式
        <intercept-url pattern="/**" access="ROLE_USER" />
        intercept-url 表示拦截页面
        /*  表示的是该目录下的资源,只包括本级目录不包括下级目录
        /** 表示的是该目录以及该目录下所有级别子目录的资源
        form-login  为开启表单登陆
    -->
    <security:http use-expressions="false">
        <security:intercept-url pattern="/**" access="ROLE_USER" />
        <!--  form-login设置开启表单登陆
                login-page:指定登录页面
                default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面
                authentication-failure-url:指定了身份验证失败时跳转到的页面。
        -->
        <security:form-login login-page="/login.html"
                             default-target-url="/success.html"
                             authentication-failure-url="/login.html"/>
        <!--关闭csrf-->
        <security:csrf disabled="true"/>
        <!-- 允许iframe -->
        <security:headers>
            <security:frame-options policy="SAMEORIGIN" />
        </security:headers>
        <!--配置退出-->
        <security:logout></security:logout>
    </security:http>
    <!-- 通过自定的用户认证类认证管理器 -->
    <!-- 自定义的用户认证类 -->
    <bean id="userService"
          class="com.wangxing.springsecuritydemo.UserDetailsServiceImpl">
    </bean>
    <!-- 密码解密方式 -->
    <bean id="passwordEncoder"
         class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>
    <security:authentication-manager>
        <security:authentication-provider user-service-ref="userService">
            <!-- 密码解密方式 -->
            <security:password-encoder ref="passwordEncoder"></security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

(6)创建自己的用户认证类

package com.wangxing.springsecuritydemo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import java.util.ArrayList;
import java.util.List;
/**
 * 用户认证类
 */
public class UserDetailsServiceImpl implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("loadUserByUsername...");
        // 定义权限类别ROLE_USER
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        // 密码是123456经过加密后的字符串
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String ps = encoder.encode("123456");
        System.out.println("密码是123456经过加密后的字符串--"+ps);
        System.out.println("username=="+username);
        if(username.equals("admin")){
            return new User(username,ps,authorities);
        }else{
            return null;
        }

    }
}

(7)创建登陆页面和用户成功页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <link rel="shortcut icon" href="#"/>
</head>
<body>
<form action='/login' method='POST'>
    <table>
        <tr>
            <td>用户名:</td>
            <td><input type='text' name='username' value=''></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type='password' name='password' /></td>
        </tr>
        <tr>
            <td colspan='2'><input name="submit" type="submit" value="登陆" /></td>
        </tr>
    </table>
</form>
</body>
</html>

SpringSecurity
账号:admin 密码:123456
SpringSecurity