ssm框架整合springSecurity

SSM整合springsecurity过程

前言:先来说一下springsecurity的作用
  1. springsecurity底层实现为一条过滤器链,就是用户请求进来,判断有没有请求的权限,抛出异常,重定向跳转
  2. springsecurity的核心功能
    • 认证 (我是谁,用户信息验证)
    • 授权 (可以做什么,权限角色)
    • 攻击防护 (防止伪造攻击,csrf)
  3. 其核心就是一组过滤器链,项目启动后将会自动配置。最核心的就是 Basic Authentication Filter 用来认证用户的身份,一个在spring security中一种过滤器处理一种认证方式。
    在这里插入图片描述
正文:我们来理一下整合过程
加入pom依赖
  1. <!--spring的依赖,用来实现web功能需求-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <!--security连接web的包,含有其他依赖包-->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
    </dependency>
    <!--security配置所需的包-->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>
    <!--security标签库的依赖包-->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
    </dependency>
    
写web.xml配置
  1. 在web.xml中加入过滤器

       <!--加入springsecurity的过滤器,实现security控制项目   -->
       <filter>
           <!--springSecurityFilterChain是默认名,不可更改,意思是security的过滤器链,在ioc容器初始化后,过滤器初始化-->
           <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>
    
创建Security基于注解的配置类,这里只是例子,两个方法开始为空
//表示当前类是配置类
@Configuration
//表示启用web下权限控制功能
@EnableWebSecurity
//启用全局方法权限控制功能,并且设置prePostEnabled=true,保证一些注解可以识别
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;
    //注入BCryptPasswordEncoder
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    //与springsecurity环境下用户登录相关
    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        //内存版登录测试
//        builder
//                .inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).
//                withUser("tom").password(new BCryptPasswordEncoder().encode("123")).roles("ADMIN");
        //连接数据库的登录策略
        builder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);;
    }

    //与springsecurity环境下授权相关
    @Override
    protected void configure(HttpSecurity security) throws Exception {

        security
                .authorizeRequests()
                .antMatchers("/admin/to/login/page.html")           //释放登录表单页面
                .permitAll()
                .antMatchers("/security/admin/do/login.html")       //释放登录的请求
                .permitAll()
                .antMatchers("/index.jsp", "/bootstrap/**", "/crowd_js/**",
                        "/css/**", "/fonts/**", "/img/**", "/jquery/**", "/layer/**", "/script/**", "/ztree/**")
                .permitAll()                    //释放上面这些静态资源
                .anyRequest()                       //禁止任何请求
                .authenticated()
                .and()
                .exceptionHandling()
                .accessDeniedHandler(new AccessDeniedHandler() {
                    @Override
                    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                        httpServletRequest.setAttribute("exception" ,new Exception(CrowdConstant.MESSAGE_ACCESS_DENIED));
                        httpServletRequest.getRequestDispatcher("/WEB-INF/system-error.jsp").forward(httpServletRequest, httpServletResponse);
                    }
                })
                .and()
                .formLogin()            //登录表单设置
                .loginPage("/admin/to/login/page.html")         //去向登录的页面
                .loginProcessingUrl("/security/admin/do/login.html")                //登录跳转的请求
                .defaultSuccessUrl("/admin/to/main/page.html")              //密码正确后跳转的页面
                .usernameParameter("loginAcct")                 //表单的用户名
                .passwordParameter("userPswd")              //表单的密码
                .and()
                .csrf()
                .disable()                      //禁用了csrf
                .logout()                                               //注销设置
                .logoutUrl("/security/admin/do/logout.html")         //注销跳的超链接
                .logoutSuccessUrl("/admin/to/login/page.html");      //注销成功后跳转的页面
    }
}
  • 这里有两个关键点

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 三个注解,以及继承WebSecurityConfigurerAdapter并重写两个****configure方法
  • 然而还有一个关键点,就是这个配置类的放置位置

在这里插入图片描述

  • 我放在了mvc包下,扫描它的是springmvc.xml这个配置文件,留个悬念!!!
来是一波分析

在这里插入图片描述

在这里插入图片描述

由图可以看到,ssm框架整合后有两个xml配置文件,一个是spring的ioc容器叫spring-*.xml ,一个是springmvc.xml配置文件。在web.xml文件里面是分别配置,分管不同的功能的。

  • application.xml是父类ioc容器,放的是service层和mapper层,以及pojo实体类的bean,里面会扫描service层和mapper,以至于放进ioc容器,可以通过@AutoWrited注入使用
    ;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

然而psringmvc.xml扫描的是mvc包,包下包含了config包
在这里插入图片描述
在这里插入图片描述

为什么要分析这些呢?
  • 因为会出现没有bean的错误springSecurityFilterChain这个bean,很眼熟吧

在这里插入图片描述

错误分析
  • 为什么会报这样的错:因为ssm中有两大容器
    • 一个是spring的ioc容器ContextLoaderListener
    • 一个是springmvc的ioc容器DispatcherServlet

在这里插入图片描述

在项目启动时:首先ContextLoaderListener初始化,其次springSecurityFilterChain初始化,最后DispatcherServlet初始化;
springSecurityFilterChain初始化时会默认去寻找springmvc的ioc容器扫描配置类

所以顺序就是:ContextLoaderListener->springSecurityFilterChain->DispatcherServlet

也可以看出来,Listener监听器—>Filter过滤器—>servlet初始化,这一规律。

错误解决方案
  • 解决方案有两种:

    1. 将springmvc的ioc容器和spring的ioc容器合二为一

    在web.xml文件中注释掉初始化ContextLoaderListener的配置

     <!--配置spring 初始化器-->
     <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-*.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    

然后在springmvc初始化文件中加入 <import resource="classpath:spring-*.xml"/>初始化spring的ioc容器的配置

在这里插入图片描述

    1. 第二种是修改源码的方法,小编就是用了这种方法的

    首先来分析我们的错误,核心原因是过滤器在加载前端控制器之前就初始化了,初始化时会去前端控制器ioc容器中找bean,那时候前端控制器根本没有
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    我们看看错误出在哪里,那个类抛的异常

    找到的是这个类org.springframework.web.filter.DelegatingFilterProxy

    我们用idea的ctrl+鼠标单击进去,在自己的项目下建立一样的包,建立一样的内容同名的类,进行对源码的修改

    这是初始化springSecurityFilterChain的过程findWebApplicationContext()这个方法就是在找容器,这时候找前端控制器是找不到的,但是找不到这里是没有处理找不到的情况的,但最后是会报封装不上springSecurityFilterChain的异常

    在这里插入图片描述

    然而我们还有机会扫描它,我们先把这一步取消掉,那就是取消了初始化springSecurityFilterChain,如上,当发起第一次请求的时候,它会执行一个叫**doFilter()**的方法,这也和一般的过滤器一般,当服务器接收到请求时,会先去到过滤器执行doFilter()方法,然后是否放行什么的操作。

    在这里插入图片描述

    又看到我们的好朋友WebApplicationContext wac = findWebApplicationContext();了吧,对,它这里又开始找ioc容器去找相应的bean,但是这个方法好像只在找spring的ioc容器的,我们需要自定义方法,从源码中我们重写了一个找ioc容器的过程

    在这里插入图片描述

修改的代码如下,获取ServletContext,然后attrName是前端控制器的全类名一样的东西,重要的是servletName,这是在web.xml对应的前端控制器的名字
在这里插入图片描述
在这里插入图片描述> 如上这些做完就完成了对源码的修改,项目启动成功了,整合也就完成了,在详细的步骤就是security配置类的编写了。

用内存版模式去搭建登录
  • 先做准备工作
    在这里插入图片描述

  • 设置登录页面的信息
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 在configure带builder的方式,使用内存版登录测试

    • 这样就可以尝试登录了。
改用数据库版的登录模式

在这里插入图片描述

  1. 建立数据库
    在这里插入图片描述 2. 编写UserDetailService子类
     package com.frf.crowd.mvc.config;
     
     import com.frf.crowd.pojo.Admin;
     import com.frf.crowd.pojo.Role;
     import com.frf.crowd.service.AdminService;
     import com.frf.crowd.service.AuthService;
     import com.frf.crowd.service.RoleService;
     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.stereotype.Component;
     
     import java.rmi.server.UID;
     import java.util.ArrayList;
     import java.util.List;
     
     /**
      * 用于springSecurity用户验证时获取用户信息
      * @author Administrator
      *
      */
     @Component
     public class CrowdUserDetialService implements UserDetailsService {
     
         @Autowired
         private AdminService adminService;
         @Autowired
         private AuthService authService;
         @Autowired
         private RoleService roleService;
         @Override
         public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
             //通过用户名查找用户
             Admin admin = adminService.get_Admin_By_Name(username);
             //获取此管理员id
             Integer adminId = admin.getId();
             //根据adminId查找角色信息
             List<Role> roleList = roleService.get_Assign_Role_By_AmindID(adminId);
             //根据adminID查找权限
             List<String> authNameList = authService.get_Assigned_AuthName_By_AdminId(adminId);
             //创建集合对象存储 权限集合——GrantedAuthority
             List<GrantedAuthority> authorities=new ArrayList<>();
             //遍历assignedRoleList存入角色信息
             for (Role role : roleList) {
                 String roleName="ROLE_"+role.getName();
                 SimpleGrantedAuthority grantedRole = new SimpleGrantedAuthority(roleName);
                 authorities.add(grantedRole);
             }
             //遍历authNameList存入权限信息
             for (String authName : authNameList) {
                 SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(authName);
                 authorities.add(grantedAuthority);
             }
             //封装到我们设置的对象中返回
             SecurityAdmin securityAdmin = new SecurityAdmin(admin, authorities);
             return securityAdmin;
         }
     }
  1. 编写封装类SecurityAdmin,User的子类

    package com.frf.crowd.mvc.config;
    
    import com.frf.crowd.pojo.Admin;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.userdetails.User;
    
    import java.util.Collection;
    import java.util.List;
    
    public class SecurityAdmin extends User {
    
        //原始的Admin对象,包含Admin对象的全部属性
        private  Admin originalAdmin;
        //重写父类的方法
        public SecurityAdmin(
                //传入封装前的Admin对象
                Admin originalAdmin,
                //传入创建角色、权限信息的集合
                List< GrantedAuthority> authorities) {
            //调用User封装
            super(originalAdmin.getUserName(), originalAdmin.getUserPswd(), authorities);
            //成员变量获取原始Admin
            this.originalAdmin=originalAdmin;
            //擦除密码
            this.originalAdmin.setUserPswd(null);
        }
        //对外提供获取原始Admin对象的get方法
        public Admin getOriginalAdmin() {
            return originalAdmin;
        }
    }
    
  2. 装配数据源

    1. 写配置文件,在初始化的时候放入ioc容器中
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      SecurityAdmin是一个经过封装的User类,继承了User类,对此,我们就可以把我们用于数据库登录的实体类作为原始类加上角色和权限封装成一个新类。

    2. 进行自动装配 到此,我们就配置基本成功了。
      在这里插入图片描述
      到此,我们就配置基本成功了。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: SSM指的是Spring+SpringMVC+MyBatis这一组合,而Spring SecuritySpring框架中用于安全认证和授权的模块。将SSM整合Spring Security,可以在SSM应用中提供更加完善的安全控制和认证功能。 具体的实现过程包括以下几个步骤: 1. 添加Spring Security依赖:在pom.xml文件中添加Spring Security的依赖,如下所示: ```xml <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>5.4.2</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>5.4.2</version> </dependency> ``` 2. 配置Spring Security:在Spring的配置文件中配置Spring Security,包括认证管理器、用户详情服务、密码加密方式、安全过滤器链等内容。 3. 编写登录页面和控制器:编写用户登录页面和控制器,用户在登录页面输入用户名和密码后,控制器将用户输入的信息交给Spring Security进行认证。 4. 配置安全规则:根据业务需求,配置安全规则,例如需要登录才能访问某些资源,或者某些资源只有特定的用户角色才能访问等。 5. 测试:启动应用,测试登录、授权等功能是否正常。 通过以上步骤,就可以将Spring Security整合SSM应用中,提供更加完善的安全控制和认证功能。 ### 回答2: ssm整合springsecurity是指将SpringSecurity框架SSM框架进行集成,实现对用户认证和授权的支持,保护Web应用程序中的资源。 具体来说,SSM框架中的Web应用程序可以使用SpringSecurity框架提供的安全机制,从而可以很好地保护应用程序中的敏感信息。此外,SpringSecurity还提供了一套完整的用户认证和授权框架,可以自定义实现用户登录、密码验证、用户授权等功能。 要实现SSM整合SpringSecurity,需要进行以下几个步骤: 1. 在pom.xml文件中添加spring-security-core和spring-security-config依赖,具体依赖根据项目需求而定。 2. 在Spring MVC的配置文件中添加SpringSecurity的配置信息,如用户权限的设置、HTTPS的启用以及记录用户登录日志等。 3. 在web.xml文件中添加SpringSecurity的Filter和配置信息。 4. 编写实现用户认证和授权的Java类,如自定义认证管理器、用户详细信息服务、密码加密服务等。 5. 编写安全相关的页面和控制器,如登录页面、注册页面、注销页面和授权页面等。 在SSM整合SpringSecurity的过程中,需要注意以下几点: 1. SpringSecurity框架提供了多种用户认证和授权的方式,开发者需要根据需求选择最适合的。 2. 在实现用户认证和授权的Java类中,需要注意代码的可读性、可维护性和安全性。 3. 在页面和控制器中,需要对用户输入的数据进行验证和过滤,防止SQL注入、跨站脚本攻击等安全问题。 总的来说,SSM整合SpringSecurity可以很好地提高Web应用程序的安全性,保护用户信息不被恶意攻击者利用,并且可以轻松地实现用户认证和授权等功能,为应用程序提供更好的用户体验。 ### 回答3: SSM是指SpringSpringMVC和Mybatis三个框架整合Spring SecuritySpring安全框架。对于SSM整合Spring Security,可以按照以下步骤进行。 1.在Spring的配置文件中添加以下内容: ``` <!--启用Spring Security--> <security:http auto-config="true"> <security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> <security:intercept-url pattern="/user/**" access="ROLE_USER" /> <security:form-login login-page="/login" username-parameter="username" password-parameter="password" /> <security:logout logout-success-url="/logout" /> </security:http> <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="admin" password="admin123" authorities="ROLE_ADMIN" /> <security:user name="user" password="user123" authorities="ROLE_USER" /> </security:user-service> </security:authentication-provider> </security:authentication-manager> ``` 2.在SpringMVC的配置文件中添加以下内容,通过@Autowired注解将上面的bean引入: ``` <!--开启注解扫描--> <context:component-scan base-package="com.example.controller" /> <!--启用Spring Security--> <security:global-method-security pre-post-annotations="enabled" /> <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy"> <security:filter-chain-map path-type="ant"> <security:filter-chain pattern="/login" filters="authenticationProcessingFilter" /> <security:filter-chain pattern="/logout" filters="logoutFilter" /> <security:filter-chain pattern="/**" filters="basicAuthenticationFilter" /> </security:filter-chain-map> </bean> <bean id="authenticationProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationSuccessHandler"> <bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/admin/index" /> </bean> </property> <property name="authenticationFailureHandler"> <bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login?error=true" /> </bean> </property> <property name="usernameParameter" value="username" /> <property name="passwordParameter" value="password" /> </bean> <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter"> <constructor-arg value="/login" /> <constructor-arg> <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" /> </constructor-arg> </bean> <bean id="basicAuthenticationFilter" class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationEntryPoint"> <bean class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> <property name="realmName" value="Spring Security Application" /> </bean> </property> </bean> <security:authentication-manager id="authenticationManager"> <security:authentication-provider user-service-ref="userDetailsService" /> </security:authentication-manager> <bean id="userDetailsService" class="com.example.service.MyUserDetailsService" /> ``` 3.在Mybatis的配置文件中,为所有需要授权的Mapper接口添加以下内容: ``` @Secured("ROLE_USER") ``` 其中ROLE_USER需要在Spring的配置文件中定义。 通过以上步骤,就可以在SSM框架整合Spring Security实现安全认证和权限控制了。在实际开发中,还需要根据具体的业务需求和系统架构进行定制,包括自定义认证和授权方式、注销登录、记住密码、登陆超时等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值