SpringSecurity安全框架(权限管理)

Spring Security安全框架

简介
  • Spring Security是 Spring提供的安全认证服务的框架(功能强大的权限管理框架)。 使用Spring Security可以帮助我们来简化认证和授权的过程。官网:https://spring.io/projects/spring-security

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

  • 授权:用户认证成功后,需要为用户授权,其实就是指定当前用户可以操作哪些功能。

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

  • RBAC:Role-Based Access Control,基于角色的访问权限控制

  • 功能:登录/认证/鉴权/登出

Spring Security环境搭建
  • pom.xml文件导入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>
    
  • web.xml文件主要配置SpringMVC的DispatcherServlet和用于整合第三方框架的DelegatingFilterProxy,用于整合Spring Security。 配置哪些请求需要让SpringSecurity来进行认证或鉴权自动管理

    <!--委派过滤器,用于整合其他框架-->
    <filter>
        <!--
          DelegatingFilterProxy用于整合第三方框架
          整合spring security时,此过滤器的名称固定springSecurityFilterChain
          否则会抛出NoSuchBeanDefinitionException异常
         -->
        <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>
    
  • 在spring-security.xml中主要配置Spring Security的拦截规则和认证管理器

    <?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:http security="none" pattern="/pages/b.html"></security:http>-->
        <!--<security:http security="none" pattern="/pages/**"></security:http>-->
        <security:http security="none" pattern="/login.html"></security:http>
        <security:http security="none" pattern="/css/**"></security:http>
        <security:http security="none" pattern="/img/**"></security:http>
        <security:http security="none" pattern="/js/**"></security:http>
        <security:http security="none" pattern="/plugins/**"></security:http>
        <!--
            auto-config:自动配置,如果设置为true,表示自动应用一些默认配置,比如框架会提供一个默认的登录页面
            use-expressions:是否使用spring security提供的表达式来描述权限
        -->
        <security:http auto-config="true" use-expressions="true">
            <security:headers>
                <!--设置在页面可以通过iframe访问受保护的页面,默认为不允许访问-->
                <security:frame-options policy="SAMEORIGIN"></security:frame-options>
            </security:headers>
            <!--配置拦截规则,/** 表示拦截所有请求-->
            <!--
                pattern:描述拦截规则
    			pattern:对哪些url进行权限控制
                asscess:指定所需的访问角色或者访问权限
                    isAuthenticated(),登录即可访问
                    hasAuthority('add'),需要有add权限,才可访问
                    hasRole('admin'),需要有admin角色,才可访问
            -->
            <!--只要认证通过就可以访问-->
            <security:intercept-url pattern="/pages/*"  access="isAuthenticated()" />
    
            <!--
    			如果我们要使用自己指定的页面作为登录页面,必须配置登录表单.页面提交的登录表单请求是由框架负责处理
                form-login:定义表单登录信息L           
                login-page:指定登录页面访问URL
    			default-target-url:登录成功后跳转的网页
    			authentication-failure-url:访问网页权限不够时,跳转的网页
            -->
            <security:form-login
                    login-page="/login.html"
                    username-parameter="username"
                    password-parameter="password"
                    login-processing-url="/login.do"          
                    default-target-url="/pages/main.html"
                    authentication-failure-url="/login.html">
            </security:form-login>
    
            <!--
              csrf:对应CsrfFilter过滤器
              disabled:是否启用CsrfFilter过滤器,如果使用自定义登录页面需要关闭此项,否则登录操作会被禁用(403)
            -->
            <security:csrf disabled="true"></security:csrf>
    
            <!--
              logout:退出登录
              logout-url:退出登录操作对应的请求路径
              logout-success-url:退出登录后的跳转页面
              invalidate-session:true销毁session
            -->
            <security:logout logout-url="/logout.do"
                             logout-success-url="/login.html" 
                             invalidate-session="true"/>
    
        </security:http>
    
        <!--配置认证管理器-->
        <security:authentication-manager>
            <!--配置认证提供者-->
            <security:authentication-provider user-service-ref="springSecurityUserService">
                <!--
                    user:定义用户信息,可以指定用户名、密码、角色,后期可以改为从数据库查询用户信息 
    				{noop}:表示当前使用的密码为明文
                <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="passwordEncoder"
              class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />
        <!--配置SpringSecurityUserService对象,通过@Component注解配置了,这里不用写该对象的bean-->
        <!--<bean id="springSecurityUserService" class="com.itheima.service.SpringSecurityUserService"/>-->
    
        <!--开启spring注解使用,在springmvc.xml配置,使用import导入springmvc.xml中-->
        <!--<context:annotation-config></context:annotation-config>-->
        <!--<mvc:annotation-driven></mvc:annotation-driven>-->
        <!--<context:component-scan base-package="com.it.controller"></context:component-scan>-->
    
        <!--开启注解方式权限控制-->
        <security:global-method-security pre-post-annotations="enabled" />
    </beans>
    
  • 从数据库动态查询用户信息,必须按照spring security框架的要求提供一个实现UserDetailsService接口的实现类,并按照框架的要求进行配置即可。框架会自动调用实现类中的方法并自动进行密码校验。

    import org.springframework.security.core.userdetails.User;
    
    
    @Component("springSecurityUserService")
    public class SpringSecurityUserService implements UserDetailsService {
    
        @Reference//通过dubbo远程调用UserService
        private UserService userService;
    
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            //远程调用用户服务,根据用户名查询用户信息
            com.ith.POJO.User user = userService.findByUsername(username);
            if(user == null){
                return null;
            }
            //动态为当前用户授权
            List<GrantedAuthority> list = new ArrayList<>();
            Set<Role> roles = user.getRoles();
            for (Role role : roles) {
                list.add(new SimpleGrantedAuthority(role.getKeyword()));
                Set<Permission> permissions = role.getPermissions();
                for (Permission permission : permissions) {
                    list.add(new SimpleGrantedAuthority(permission.getKeyword()));
                }
            }
            UserDetails userDetails = new User(username, user.getPassword(), list);
            return userDetails;
        }
    }
    
  • controller加上注解进行权限控制

    import org.springframework.security.core.userdetails.User;
    
    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Reference//通过dubbo远程调用UserDao
        private UserDao userDao;
        //从上下文中获取当前登录人的信息和权限
        @RequestMapping("/getUsername")
        public Result getUsername(){
            //当Spring security完成认证后,会将当前用户信息保存到框架提供的上下文对象
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            if(user != null){
                String username = user.getUsername();
                return new Result(true, MessageConstant.GET_USERNAME_SUCCESS,username);
            }
    
            return new Result(false, MessageConstant.GET_USERNAME_FAIL);
        }
        
        @PreAuthorize("hasAuthority('DELETE')")//权限校验
        @RequestMapping("delete")
        public Result delete(Integer id) {
            try {
                userService.delete(id);
            } catch (Exception e) {
                e.printStackTrace();
                return new Result(false, MessageConstant.DELETE_USER_FAIL);
            }
            return new Result(true, MessageConstant.DELETE_USER_SUCCESS);
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值