SpringSecurity_授权认证

SpringSecurity是一个基于AOP和Servlet过滤器的安全框架,提供认证和授权功能。文章介绍了SpringSecurity所需的依赖,包括spring-security-config和spring-security-taglibs等,并展示了如何在web.xml中配置监听器和过滤器,以及核心配置文件中设置http安全、拦截URL、登录和注销等功能。此外,文章还提到了密码加密和自定义登录页面的实现。
摘要由CSDN通过智能技术生成

前言

SpringSecurity 是 spring 采用 AOP 思想,基于 servlet 过滤器实现的安全框架。它提供了完善的认证机制和方法级的授权功能。是一款非常优秀的权限管理框架。
权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源。权限管理几乎出现在任何系统里面,前提是需要有用户和密码认证的系统。
认证:通过用户名和密码成功登陆系统后,让系统得到当前用户的角色身份。
授权:系统根据当前用户的角色,给其授予对应可以操作的权限资源。

核心内容

SpringSecurity所需依赖

SpringSecurity需要的引入的依赖,
spring-security-core.jar 核心包,任何 SpringSecurity 功能都需要此包。
spring-security-web.jar web 工程必备,包含过滤器和相关的 Web 安全基础结构代码。
spring-security-config.jar 用于解析 xml 配置文件,用到 SpringSecurity 的 xml配置文件的就要用到此包。
spring-security-taglibs.jarSpringSecurity 提供的动态标签库,jsp 页面可以用。

	<dependencies>
        <!--spring依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.25</version>
        </dependency>
        <!--springmvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.3.25</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.25</version>
        </dependency>
		<!--servlet-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        
	    <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.30</version>
            <scope>test</scope>
        </dependency>
		<!--SpringSecurity-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>5.3.13.RELEASE</version>
        </dependency>
	    <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-taglibs</artifactId>
            <version>5.3.13.RELEASE</version>
        </dependency>
    </dependencies>

由于和 web 工程集成,我们在项目中可以不用引入 core 和 web 的依赖。因为 spring 工程有 spring-core 包,springmvc 有 spring-web 包。可以依赖传递过来。

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
         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">
	<!--配置监听器,在项目启动时加载SpringSeurity核心配置文件-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springSecurity.xml</param-value>
    </context-param>
	<!--
		配置认证授权过滤器
		这里filter-name的名称,只能是springSecurityFilterChain!!!!
	-->
    <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>

SpringSuecrity的核心配置文件

<?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 security="none" pattern="/css/**"></security:http>
    <security:http security="none" pattern="/img/**"></security:http>
    <security:http security="none" pattern="/plugins/**"></security:http>

    <security:http auto-config="true" use-expressions="true">

    <security:intercept-url pattern="/login.jsp" access="permitAll()"></security:intercept-url>

    <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"></security:intercept-url>

    <security:form-login login-page="/login.jsp"
                             login-processing-url="/login"
                             username-parameter="username"
                             password-parameter="password"
                             default-target-url="/index.jsp"
                             authentication-failure-forward-url="/failer.jsp"/>

    <security:csrf disabled="true"/>

    <security:logout logout-url="/logout"
                         invalidate-session="true"
                         logout-success-url="/login.jsp"/>

    <security:remember-me token-validity-seconds="3600"/>
    </security:http>

	<!--配置认证管理器-->
    <security:authentication-manager>
   		<!--配置认证提供者-->
        <security:authentication-provider user-service-ref="userServiceImpl">
			<!--配置加密方式-->
            <security:password-encoder ref="bCryptPasswordEncoder"></security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>

<!--配置加密工具类-->
    <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>

</beans>

细节:

  1. <security:http security="none" pattern="/css/**"></security:http>
    静态资源不过滤,直接放行,没有什么好说的
  2. <security:http auto-config="true" use-expressions="true"> 3/4/5/6/7/8 </security:http>
    auto-config=“true”: 开启Spring-Security 的自动配置
    use-expressions=“true”: 允许使用Spring表达式
  3. <security:intercept-url pattern="/login.jsp" access="permitAll()"></security:intercept-url>
    表示登录页面可以被任何用户访问,不需要任何权限
  4. <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_ADMIN','ROLE_USER')"></security:intercept-url>
    pattern: 拦截的请求资源
    access: 访问资源所需要的角色
    这里access有很多写法,例如:access="hasAnyAuthority('ADMIN','USER')"
    在这里插入图片描述
  5. 自定义登录页面
    这里为什么说是自定义一个登录页面呢?难道还有一个自带的登陆页面?没错,SpringSecurity本身携带一个巨丑的首页。
<security:form-login login-page="/login.jsp"
                             login-processing-url="/login"
                             username-parameter="username"
                             password-parameter="password"
                             default-target-url="/index.jsp"
                             authentication-failure-forward-url="/failer.jsp"/>

login-page:自定义的登录页面
login-processing-url:表单提交之后,交给 action 去处理 springSecurity 默认提供了一个叫/login 的逻辑处理。
username-parameter:值必须和登录表单里面的控件名称保持一致。
password-parameter:值必须和登录表单里面的控件名称保持一致。
authentication-failure-forward-url:认证失败之后,需要跳转的页面。
default-target-url:认证成功之后,需要跳转的页面。
在这里插入图片描述

  1. <security:csrf disabled="true"/>
    ajax 提交时使用这个<security:csrfMetaTags/>
    CSRF(Cross-siterequestforgery)跨站请求伪造,是一种难以防范的网络攻击方式。
    在这里插入图片描述
    关闭csrf,默认是开启的,开启后项目中的所有表单提交都必须携带<security:csrfInput/>,不推荐禁用,关闭后不太安全,这里关闭是因为,我授权认证是我项目写完之后加上的。

  2. 配置注销登录后跳转的页面

 <security:logout logout-url="/logout"
 						<!--销毁session-->
                         invalidate-session="true"
                         <!--注销成功后返回登录页-->
                         logout-success-url="/login.jsp"/>

在这里插入图片描述

  1. <security:remember-me token-validity-seconds="3600"/>
    开启一定时间的免密登录
    token-validity-seconds:指定时间,单位秒
    在这里插入图片描述

注意:第3-8点都是在2标签内部

  1. 实现认证功能和密码加密
<!--配置认证管理器-->
    <security:authentication-manager>
   		<!--配置认证提供者 注入-->
        <security:authentication-provider user-service-ref="userServiceImpl">
			<!--配置加密方式-->
            <security:password-encoder ref="bCryptPasswordEncoder"></security:password-encoder>
        </security:authentication-provider>
    </security:authentication-manager>

<!--配置密码加密工具类-->
    <bean id="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean>

实现步骤:

  1. 让我们自己的 UserService 接口继承 UserDetailsService
public interface UserService extends UserDetailsService{}
  1. 定义 UserServiceImpl 类,实现这个接口,编写 loadUserByUsername 业务
 public class UserServiceImpl implements UserService {
 //重写方法 核心方法
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = this.findUserByUserName(username);
        List<Role> roles = userInfo.getRoles();
        User user = new User(userInfo.getUsername(),userInfo.getPassword(),getAuthorities(roles));
        return user;
    }

    /**
     * 获取所有的权限集合
     */
    private Collection<? extends GrantedAuthority> getAuthorities(List<Role> roles) {
        List<SimpleGrantedAuthority> authorityList = new ArrayList<>();
        for (Role role : roles) {
            authorityList.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));
//            List<Permission> permissions = role.getPermissions();
//            for (Permission permission : permissions) {
//                authorityList.add(new SimpleGrantedAuthority("ROLE_" + permission.getPermissionName()));
//            }
        }
        return authorityList;
    }
}

授权

说明:SpringSecurity 可以通过注解的方式来控制类或者方法的访问权限。注解需要对应的注解支持,若注解放在 controller 类中,对应注解支持应该放在 mvc 配置文件中,因为 controller 类是有 mvc 配置文件扫描并创建的,同理,注解放在 service 类中,对应注解支持应该放在 spring 配置文件中。

<!--开启使用注解表达式使用支持-->
 <security:global-method-security pre-post-annotations="enabled" proxy-target-class="true"/>
  1. @Secured
    @Secured 是专门用于判断是否具有角色的。能写在方法或类上。 参数要以 ROLE_开头.
  2. @PreAuthorize/@PostAuthorize
    @PreAuthorize 和@PostAuthorize 都是方法或类级别注解。
    @PreAuthorize 表示访问方法或类在执行之前先判断权限,大多情况下都是使用这个注解,注解的参数和access()方法参数取值相同,都是权限表达式。
    @PostAuthorize 表示方法或类执行结束后判断权限,此注解很少被使用到
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值