springSecurity-入门到实战(整合SSM-整合Springboot待更新)

SpringSecurty

认证和授权概念

前面我们已经完成了传智健康后台管理系统的部分功能,例如检查项管理、检查组管理、套餐管理、预 约设置等。接下来我们需要思考2个问题:

问题1:在生产环境下我们如果不登录后台系统就可以完成这些功能操作吗? 答案显然是否定的,要操作这些功能必须首先登录到系统才可以。

问题2:是不是所有用户,只要登录成功就都可以操作所有功能呢? 答案是否定的,并不是所有的用户都可以操作这些功能。

不同的用户可能拥有不同的权限,这就需要进 行授权了。

 

认证:系统提供的用于识别用户身份的功能,通常提供用户名和密码进行登录其实就是在进行认证,认 证的目的是让系统知道你是谁。

授权:用户认证成功后,需要为用户授权,其实就是指定当前用户可以操作哪些功能。 本章节就是要对后台系统进行权限控制,其本质就是对用户进行认证和授权。

 

Spring Security简介

Spring Security是 Spring提供的安全认证服务的框架。 使用Spring Security可以帮助我们来简化认证 和授权的过程。

官网:https://spring.io/projects/spring-security

对应的maven坐标:

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

常用的权限框架除了Spring Security,还有Apache的shiro框架。

 

SpringSecurty初体验

1、导入对应坐标

自己添加一下版本

 <dependencies>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
        </dependency>
        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.miemiedev</groupId>
            <artifactId>mybatis-paginator</artifactId>
        </dependency>
        <!-- MySql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <!-- dubbo相关 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>
 </dependencies>
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <configuration>
          <!-- 指定端口 -->
          <port>85</port>
          <!-- 请求路径 -->
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>

2、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>
    <!--
    DelegatingFilterProxy用于整合第三方框架
    整合Spring Security时过滤器的名称必须为springSecurityFilterChain,
    否则会抛出NoSuchBeanDefinitionException异常
  -->
    <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>

  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-security.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

3、配置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:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://code.alibabatech.com/schema/dubbo
						http://code.alibabatech.com/schema/dubbo/dubbo.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd
                     http://www.springframework.org/schema/security
                     http://www.springframework.org/schema/security/spring-security.xsd">
    <!--
       auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面
       use-expressions:是否使用spring security提供的表达式来描述权限
   -->
    <security:http auto-config="true" use-expressions="true">
        <!--配置拦截规则,/** 表示拦截所有请求-->
        <!--
            pattern:描述拦截规则
            asscess:指定所需的访问角色或者访问权限
        -->
        <security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"></security:intercept-url>

    </security:http>

    <!--配置认证管理器-->
    <security:authentication-manager>
        <!--配置认证提供者-->
        <security:authentication-provider>
            <!--配置一个具体的用户,后期需要从数据库查询用户 -->
            <security:user-service>
                <security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>
</beans>

4、测试

准备一个index.html 页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
 hello ! welcome securty!!!
</body>
</html>

启动tomcat --》

登录后访问index.html页面即可!!! 此登录页面是security自带的!!!

 

更加详细的入门案例可参考:

https://blog.csdn.net/qq_45441466/article/details/109371359 
 

SpringSecurty改进版本

前面我们已经完成了Spring Security的入门案例,通过入门案例我们可以看到,Spring Security将我们 项目中的所有资源都保护了起来,要访问这些资源必须要完成认证而且需要具有ROLE_ADMIN角色。

但是入门案例中的使用方法离我们真实生产环境还差很远,还存在如下一些问题:

1、项目中我们将所有的资源(所有请求URL)都保护起来,实际环境下往往有一些资源不需要认证也 可以访问,也就是可以匿名访问。

2、登录页面是由框架生成的,而我们的项目往往会使用自己的登录页面。

3、在配置文件中配置的密码使用明文,这非常不安全,而真实生产环境下密码需要进行加密。

本章节需要对这些问题进行改进。

 

配置可匿名访问的资源



第一步:在项目中创建pages目录,在pages目录中创建a.html和b.html

第二步:在spring-security.xml文件中配置,指定哪些资源可以匿名访问

    <!--配置哪些资源匿名可以访问(不登录可以访问)-->
    <security:http security="none" pattern="/pages/a.html"/>
    <security:http security="none" pattern="/pages/b.html"/>

即是当前pages目录下的a.html 和 b.html 页面进行权限校验

 

也可以配置pages/** 放在pages目录下所有资源不校验权限

    <security:http security="none" pattern="pages/**"></security:http>

通过上面的配置可以发现,pages目录下的文件可以在没有认证的情况下任意访问。

 

使用指定的登录页面

第一步:提供login.html作为项目的登录页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<form action="/login.do" method="post">
  username:<input type="text" name="username"><br>
  password:<input type="password" name="password"><br>
  <input type="submit" value="submit">
</form>
</body>
</html>

第二步:修改spring-security.xml文件,指定login.html页面可以匿名访问

    <security:http security="none" pattern="/login.html"/>

第三步:修改spring-security.xml文件,加入表单登录信息的配置

配置在<security:http> 标签中:

<!--如果我们要使用字节指定的页面作为登录页面,必须配置登录表单,页面提交的登录表单请求是由框架进行处理-->
        <!--
            login-page:指定登录页面访问URL
            username-password:表单请求参数
            login-processing-url:请求地址
            default-target-url: 认证成功 默认跳转页面
            authentication-failure-url: 认证失败 跳转url
        -->
        <security:form-login
                login-page="/login.html"
                login-processing-url="/login.do"
                username-parameter="username"
                password-parameter="password"
                default-target-url="/index.html"
                authentication-failure-url="/login.html"
                />

第四步:修改spring-security.xml文件,关闭CsrfFilter过滤器

csrf: spring security 用于防止跨域攻击的!!

        <!--
            csrf:对应CsrfFilter过滤器
            disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁
            用(403)
        -->
        <security:csrf disabled="true"></security:csrf>

 

从数据库查询用户信息

如果我们要从数据库动态查询用户信息,就必须按照spring security框架的要求提供一个实现 UserDetailsService接口的实现类,并按照框架的要求进行配置即可。框架会自动调用实现类中的方法 并自动进行密码校验。

实现类代码:

package com.itheima.service;

import com.itheima.pojo.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author panghl
 * @Date 2021/5/3 14:34
 * @Description TODO
 **/
public class SpringSecurityUserService implements UserDetailsService {

    public static Map<String, User> userMap = new HashMap<>();

    static {
        User user1 = new User();
        user1.setUsername("xiaoming");
        user1.setPassword("12345");

        User user2 = new User();
        user2.setUsername("admin");
        user2.setPassword("admin");

        userMap.put(user1.getUsername(), user1);
        userMap.put(user2.getUsername(), user2);
    }

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("用户输入的用户名为:" + username);
        // 根据用户名查询数据库获得用户信息(包含数据库中存储的密码信息)  --static代码块模拟了数据
        User user = userMap.get(username);
        if (user == null) {
            //用户名不存在
            return null;
        } else {
            // 将用户信息返回给框架
            // 框架会进行密码比对(页面提交的密码和数据库中查询的密码进行比对)
            List<GrantedAuthority> list = new ArrayList<>();
            //为当前登录用户授权,后期需要改为从数据库查询当前用户对应的权限
            list.add(new SimpleGrantedAuthority("permission_a"));//授予权限
            list.add(new SimpleGrantedAuthority("permission_b"));
            if (username.equals("admin")) {
                //用户名为admin 才授予ADMIN角色权限--即可登录
                list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));//授予角色
            }
            org.springframework.security.core.userdetails.User securityUser =
                    new org.springframework.security.core.userdetails.User(username, "{noop}" + userMap.get(username).getPassword(),
                            true, true, true, true, list);

            return securityUser;
        }
    }

}

 

重启tomcat测试可知:admin拥有ADMIN角色可以登录,而xiaoming则没有ADMIN角色不能登录!

 

详细查数据库玩法可看:https://blog.csdn.net/qq_45441466/article/details/109372046

 

对密码进行加密

前面我们使用的密码都是明文的,这是非常不安全的。一般情况下用户的密码需要进行加密后再保存到 数据库中。

常见的密码加密方式有:

3DES、AES、DES:使用对称加密算法,可以通过解密来还原出原始密码

MD5、SHA1:使用单向HASH算法,无法通过计算还原出原始密码,但是可以建立彩虹表进行查表破 解

bcrypt:将salt随机并混入最终加密后的密码,验证时也无需单独提供之前的salt,从而无需单独处理 salt问题

 

加密后的格式一般为:

$2a$10$/bTVvqqlH9UiE0ZJZ7N2Me3RIgUCdgMheyTgV0B4cMCSokPa.6oCa

加密后字符串的长度为固定的60位。其中:$是分隔符,无意义;2a是bcrypt加密版本号;10是cost的值;而后的前22位是salt值;再然后的字符串就是密码的密文了。

 

实现步骤:

第一步:在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:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://code.alibabatech.com/schema/dubbo
						http://code.alibabatech.com/schema/dubbo/dubbo.xsd
						http://www.springframework.org/schema/context
						http://www.springframework.org/schema/context/spring-context.xsd
                     http://www.springframework.org/schema/security
                     http://www.springframework.org/schema/security/spring-security.xsd">
    <!--配置哪些资源匿名可以访问(不登录可以访问)-->
    <!--    <security:http security="none" pattern="/pages/a.html"/>-->
    <!--    <security:http security="none" pattern="/pages/b.html"/>-->
    <!--    <security:http security="none" pattern="pages/**"></security:http>-->

    <security:http security="none" pattern="/login.html"/>

    <!--
       auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面
       use-expressions:是否使用spring security提供的表达式来描述权限
    -->
    <security:http auto-config="true" use-expressions="true">
        <!--配置拦截规则,/** 表示拦截所有请求-->
        <!--
            pattern:描述拦截规则
            asscess:指定所需的访问角色或者访问权限
        -->
        <security:intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"></security:intercept-url>

        <!--如果我们要使用字节指定的页面作为登录页面,必须配置登录表单,页面提交的登录表单请求是由框架进行处理-->
        <!--
            login-page:指定登录页面访问URL
            username-password:表单请求参数
            login-processing-url:请求地址
            default-target-url: 认证成功 默认跳转页面
            authentication-failure-url: 认证失败 跳转url
        -->
        <security:form-login
                login-page="/login.html"
                username-parameter="username"
                password-parameter="password"
                login-processing-url="/login.do"
                default-target-url="/index.html"
                authentication-failure-url="/login.html"
        />
        <!--
            csrf:对应CsrfFilter过滤器
            disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁
            用(403)
        -->
        <security:csrf disabled="true"></security:csrf>

    </security:http>

    <!--配置认证管理器-->
    <security:authentication-manager>
        <!--配置认证提供者-->
        <security:authentication-provider user-service-ref="userService2">
            <!--配置一个具体的用户,后期需要从数据库查询用户
            <security:user-service>
                <security:user name="admin" password="{noop}1234" authorities="ROLE_ADMIN"/>
            </security:user-service>-->
            <!--指定对密码进行加密的对象-->
            <security:password-encoder ref="passwordEncoder"></security:password-encoder>

        </security:authentication-provider>
    </security:authentication-manager>
    

    <!--    <bean id="userService" class="com.itheima.service.SpringSecurityUserService"></bean>-->
    <bean id="userService2" class="com.itheima.service.SpringSecurityUserService2"></bean>

    <!--配置密码加密对象-->
    <bean id="passwordEncoder"
          class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>

    <!--开启spring注解使用-->
    <context:annotation-config></context:annotation-config>
</beans>

第二步:修改UserService实现类

package com.itheima.service;

import com.itheima.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author panghl
 * @Date 2021/5/3 14:34
 * @Description TODO
 **/
public class SpringSecurityUserService2 implements UserDetailsService {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    public Map<String, User> userMap = new HashMap<>();

    public void initUserData() {
        User user1 = new User();
        user1.setUsername("xiaoming");
        user1.setPassword(passwordEncoder.encode("12345"));

        User user2 = new User();
        user2.setUsername("admin");
        user2.setPassword(passwordEncoder.encode("admin"));//使用bcrypt提供的方法对密码加密

        userMap.put(user1.getUsername(), user1);
        userMap.put(user2.getUsername(), user2);
    }



    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("用户输入的用户名为-->2-->:" + username);
        this.initUserData();
        // 根据用户名查询数据库获得用户信息(包含数据库中存储的密码信息)  --static代码块模拟了数据
        User user = userMap.get(username);
        if (user == null) {
            //用户名不存在
            return null;
        } else {
            // 将用户信息返回给框架
            // 框架会进行密码比对(页面提交的密码和数据库中查询的密码进行比对)
            List<GrantedAuthority> list = new ArrayList<>();
            //为当前登录用户授权,后期需要改为从数据库查询当前用户对应的权限
            list.add(new SimpleGrantedAuthority("permission_a"));//授予权限
            list.add(new SimpleGrantedAuthority("permission_b"));
            if (username.equals("admin")) {
                //用户名为admin 才授予ADMIN角色权限--即可登录
                list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));//授予角色
            }
            org.springframework.security.core.userdetails.User securityUser =
                    new org.springframework.security.core.userdetails.User(username,user.getPassword(),
                            true, true, true, true, list);

            return securityUser;
        }
    }

}

通过debug可以发现密码以及通过bcrypt方式加密了!

 

补充:

对称算法:把原文A计算为密文B。同时,使用算法的逆运算,还可以把密文B还原为原文A。一般用于信息传输加密。

非对称算法: 一般是一些摘要算法,算法不可逆。即使知道算法的全部内容,也无法还原原文。

原文A计算为密文B,密文B不包含原文的所有信息,仅仅是使用原文计算出来的一个单独字符串,无法还原

 

配置多种校验规则

为了测试方便,首先在项目中创建a.html、b.html、c.html、d.html几个页面

修改spring-security.xml文件

        <!--只要认证通过就可以访问-->
        <security:intercept-url pattern="/index.jsp" access="isAuthenticated()"/>
        <security:intercept-url pattern="/pages/a.html" access="isAuthenticated()"/>

        <!--拥有add选前就可以访问b.html页面-->
        <security:intercept-url pattern="/pages/b.html" access="hasAuthority('add')"/>

        <!--拥有ROLE_ADMIN角色就可以访问c.html页面-->
        <security:intercept-url pattern="/pages/c.html" access="hasRole('ROLE_ADMIN')"/>

        <!--拥有ROLE_ADMIN角色就可以访问d.html页面,
        注意:此处虽然写的是ADMIN角色,框架会自动加上前缀ROLE_-->
        <security:intercept-url pattern="/pages/d.html" access="hasRole('ADMIN')"/>

修改实现类代码:

                list.add(new SimpleGrantedAuthority("add"));//授予权限

 测试可知:

xiaoming通过认证就可以访问index.jsp 和 pages目录下的a.html 

而admin用户通过认证可以访问pages目录下的所有html页面。

 

注解方式控制权限

SpringSecurity除了可以在配置文件中配置权限校验规则,还可以使用注解方式控制类中方法的调用。例如:Controller中的某个方法要求必须具有某个权限才能可以访问,此时就可以使用Spring Security框架提供的注解方式进行控制

实现步骤:

第一步:在spring-security.xml文件中配置组件扫描,用于扫描Controller

    <mvc:annotation-driven></mvc:annotation-driven>
    <context:component-scan base-package="com.itheima.controller"></context:component-scan>

第二步:在spring-security.xml文件中开启权限注解支持

    <!--开启注解方式权限控制-->
    <security:global-method-security pre-post-annotations="enabled"></security:global-method-security>

第三步:创建Controller类并在Controller的方法上加入注解进行权限控制

package com.itheima.controller;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author panghl
 * @Date 2021/5/3 16:13
 * @Description TODO
 **/
@RestController
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping("/add")
    @PreAuthorize("hasAuthority('add')") //调用此方法要求当前用户具有add权限
    public String add(){
        System.out.println("add....");
        return "success-add";
    }

    @RequestMapping("/delete")
    @PreAuthorize("hasRole('ROLE_ADMIN')") //调用此方法要求当前用户具有ROLE_ADMIN角色
    public String delete(){
        System.out.println("delete....");
        return "success-delete";
    }


}

 

通过测试可知:

xiaoming是无法访问add / delete方法的,admin是可以操作这两个方法的!!!

 

spring-security实现方法级别、@Secured注解、JSR-250注解、页面端的权限控制:https://blog.csdn.net/qq_45441466/article/details/109558624

 

退出登录

用户完成登录后SpringSecurity框架会记录当前用户认证状态为已认证状态,即表示用户登录成功了。那用户如何退出登录呢?我们可以在spring-security.xml文件中进行如下配置:

 <!--
        logout: 退出登录
        logout-url: 退出登录操作对应的请求路径
        logout-success-url:退出登录后跳转的页面
        -->
        <security:logout logout-url="/logout.do"
                         logout-success-url="/login.html"
                         invalidate-session="true"></security:logout>

通过上面的配置可以发现,如果用户要退出登录,只需要请求/logout.do这个URL地址就可以,同时会将当前session失效,最后页面会跳转到login页面。

 

 

 

想要获取黑马、尚硅谷等资源课程、资料、项目实战等等更多资源。可加群:1164437770(期待您的加入一起讨论)
 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值