SSM整合SpringSecurity

SSM整合SpringSecurity

前言:介绍SpringSecurity,简单来说,你可以在这设置给需要保护的资源上一把锁,也可以给某些请求一把钥匙允许其访问。这里的锁指的是访问需要的权限或者角色。钥匙就是对应的权限或者角色。正如其官网图标。
SpringSecurity官网图标

引入pom依赖

   <!-- SpringSecurity 对 Web 应用进行权限管理 -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>4.2.10.RELEASE</version>
    </dependency>
    <!-- SpringSecurity 配置 -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>4.2.10.RELEASE</version>
    </dependency>
            <!-- SpringSecurity 标签库 -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>4.2.10.RELEASE</version>
    </dependency>
       

编写自定义的配置类

@Configuration
@EnableWebSecurity
public class WebAppSercurityConfig extends WebSecurityConfigurerAdapter {

使用@Configuration注解把该类标记为配置类
使用@EnableWebSecurity:1: 加载了WebSecurityConfiguration配置类。2: 加载了AuthenticationConfiguration, 配置了认证信息。

在配置类中进行定制化

在配置类中重写 protected void configure(HttpSecurity security) 方法,设置锁

@Override
    protected void configure(HttpSecurity security) throws Exception {
        security.authorizeRequests()
                .antMatchers("/admin/to/login/page.html") // 放行登录页
                .permitAll()
                .antMatchers("/bootstrap/**") // 放行静态资源
                .permitAll()
                .antMatchers("/admin/get/page.html") //针对分页显示Admin数据设定访问控制
        
                .access("hasRole('经理') or hasAuthority('user:get')") // 具有相应角色或者权限就能访问
                .antMatchers("/admin/save.html")
                .hasRole("经理")// 要求具备经理角色
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()// 开启表单登录
                .loginPage("/admin/to/login/page.html")// 登录页
                .loginProcessingUrl("/security/do/login.html")// 验证登陆的地址
                .defaultSuccessUrl("/admin/to/main/page.html")// 登陆成功后去的地址
                .usernameParameter("loginAcct") // 自定义登录表单参数名 默认为:username
                .passwordParameter("userPswd")// 自定义登录表单参数名 默认为:password
                .and()
                .logout() // 开启退出登录功能
                .logoutUrl("/security/do/logout.html") // 退出登录请求
                .logoutSuccessUrl("/admin/to/login/page.html") // 退出登陆后前往的地址
                ;

        security.csrf().disable();// 禁用csrf功能

    }

重写protected void configure(AuthenticationManagerBuilder auth)方法 分配钥匙

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        // 认证信息在内存中实现
       /* auth.inMemoryAuthentication()
                .withUser("zs").password("123").roles("ADMIN");*/

        // 正式功能中使用基于数据库的认证
        auth.userDetailsService(userdetaileservice).passwordEncoder(getbbryptPasswordEncoder());

    }

错误解决

这时你在启动时,可能会报这样的错误:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' available

错误分析

为什么会报这样的错:因为ssm中有两大容器

  • 一个是spring的ioc容器:ContextLoaderListener
  • 一个是springmvc的ioc容器:DispatcherServlet

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

解决方案:

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

做法:

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

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

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

在这里插入图片描述
此时你的项目是能够运行的。

分配权限——数据库版

1、在springsercurity中重写父类方法

  @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {   
      // 正式功能中使用基于数据库的认证      auth.userDetailsService(userdetaileservice).passwordEncoder(getbbryptPasswordEncoder());

    }

2、建立数据库(建库语句)

3、装配数据源
在这里插入图片描述

  • 写配置文件,在初始化的时候放入ioc容器中
  • 进行自动装配

在这里插入图片描述

4、写一个userDetailsService的实现类

@Service
public class CrowdUserDetailService implements UserDetailsService {


    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AuthService authService;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 根据username查询出admin对象
        Admin admin=adminService.selectByLoginAcct(username);

        // 根据adminid取出用户拥有的角色和权限
        Integer adminId=admin.getId();
        List<Role> assignedRoleList = roleService.getAssignedRoleList(adminId);
        List<String> assignedAuthNameByAdminId = authService.getAssignedAuthNameByAdminId(adminId);
        List<GrantedAuthority> authorities=new ArrayList<>();

        // 把角色和权限进行循环封装存入

        for (Role role : assignedRoleList) {

            String name="ROLE_"+role.getName();
            SimpleGrantedAuthority simpleGrantedAuthority=new SimpleGrantedAuthority(name);
            authorities.add(simpleGrantedAuthority);


        }
        for (String s : assignedAuthNameByAdminId) {

            SimpleGrantedAuthority simpleGrantedAuthority=new SimpleGrantedAuthority(s);
            authorities.add(simpleGrantedAuthority);
        }
        SercurityAdmin sercurityAdmin=new SercurityAdmin(admin,authorities);
        return sercurityAdmin;

    }
}
  • 在实现类中根据用户名查询出用户,比较密码
  • 分配权限和角色

5、编写User子类

public class SercurityAdmin extends User {

    private Admin originalamin;

    public  SercurityAdmin(Admin admin, List<GrantedAuthority> list){

        super(admin.getLoginAcct(),admin.getUserPswd(),list);
        this.originalamin=admin;
        // 将密码擦除,提升系统整体安全性
        this.originalamin.setUserPswd(null);
    }

    public Admin getOriginalamin() {
        return originalamin;
    }

    public void setOriginalamin(Admin originalamin) {
        this.originalamin = originalamin;
    }
}

权限控制——页面元素

1、引入标签库
<%@taglib prefix="sercurity" uri="http://www.springframework.org/security/tags" %>

2、设置相应的权限或者角色,登入用户有相应的角色或者权限才能访问

 <sercurity:authorize access="hasRole('经理')">
            <div class="col-xs-6 col-sm-3 placeholder">
              <img data-src="holder.js/200x200/auto/sky" class="img-responsive" alt="Generic placeholder thumbnail">
              <h4>Label</h4>
              <span class="text-muted">Something else</span>
            </div>
 </sercurity:authorize>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值