栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringSecurity-安全框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringSecurity-安全框架

权限管理

至少离不开五张表(最基本的)

用户表,

角色表,

权限表,

(角色表和权限表可能是多对多)角色和权限的中间表,

用户表和角色表的中间表,

 1.概述

Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。

 SpringSecurity VS Shiro

1、Spring Security 基于Spring 开发,项目若使用 Spring 作为基础,配合 Spring Security 做权限更加方便,而 Shiro 需要和 Spring 进行整合开发;

2、Spring Security 功能比 Shiro 更加丰富些,例如安全维护方面;

3、Spring Security 社区资源相对比 Shiro 更加丰富;

4、Shiro 的配置和使用比较简单,Spring Security 上手复杂些;

5、Shiro 依赖性低,不需要任何框架和容器,可以独立运行;Spring Security 依赖Spring容器;

认证和授权

什么是认证?

认证 - 简单的来讲就是校验身份信息,确定用户身份是否有效(你是谁?)

例如使用传统的账号密码校验(类似于appId和密钥)和使用session和token校验等。

什么是授权?

授权简单的来讲就是校验权限,确定有效用户是否有权限访问资源(你能做什么?)

2.SpringBoot整合SpringSecurity

2.1 添加依赖


	org.springframework.boot
	spring-boot-starter-security

2.2 配置核心适配器

import com.qf.authserver.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //禁用基本认证方式
                .httpBasic().disable()
                //禁用csrf防御
                .csrf().disable()
                //开启表单认证
                .formLogin()
                //配置访问登录页的url
                .loginPage("/toLogin")
                //配置进行登录发送的请求,Security会处理该url进行登录认证
                .loginProcessingUrl("/goLogin")
                //登录失败后触发的url
                .failureForwardUrl("/toLogin?error=1")
                //登录成功后触发的url
                .successForwardUrl("/toIndex")
                //表示前面的请求都放行
                .permitAll()
                .and()
                .logout()
                //配置注销的url
                .logoutUrl("/logout")
                //放行注销请求
                .permitAll()
                .and()
                //任意请求都要通过授权访问
                .authorizeRequests().anyRequest().permitAll();
    }
}

注意:一但接入了SpringSecurity之后,登录认证的过程必须交给SpringSecurity来做,默认用户名user,密码会在控制台出现

 2.3 自己写的login




    
    Title


    登录页

    用户名或者密码错误

    
用户名:
密码:

2.4 提供跳转到页面的Controller方法

   
    @RequestMapping("/tologin")
    public String toLogin(){
        return "login";
    }

 2.5 自定义认证过程

思考:

1.如何让SpringSecurity使用我们自己的认证过程?(比如访问数据库)

2、如何让SpringSecurity知道我们自己创建的User对象(或其他对象)代表当前认证用户?

2.6 自定义认证业务实现指定接口

import org.springframework.security.core.userdetails.UserDetailsService;

public interface IUserService extends UserDetailsService {

}


import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements IUserService {

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		//访问数据库认证用户信息
        return null;
    }
}

2.7 自定义用户对象实现指定接口 (UserDetails)

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable, UserDetails {

    private Integer id;
    private String username;
    private String password;
    private String name;

    
    @Override
    public Collection getAuthorities() {
        //返回当前用户角色/权限信息
        return null;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

2.8 配置自定义认证,在security核心适配器重写配置

   @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }

 从security4.0以后,密码必须配置加密方式,如果密码没有加密,就会报以上的错误

2.9 自定义鉴权过程

@Component
public class PerssionHandler {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    
    public boolean hasPerssion(HttpServletRequest request, Authentication authentication){
        //判断当前发送的请求的url
        String requestURI = request.getRequestURI();
        //判断是否通过了身份认证
        Object principal = authentication.getPrincipal();//该方法可以获得通过了security身份认证的UserDetails对象
        if(principal instanceof UserDetails){
            //说明当前已经通过了身份认证
            //进行权限的判定
            UserDetails user = (UserDetails) principal;
            //获得当前登录用户的所有权限
            Collection authorities = user.getAuthorities();
            for (GrantedAuthority authority : authorities) {
                System.out.println("请求的url:" + requestURI + " 拥有的url:" + authority.getAuthority());

                if (antPathMatcher.match(requestURI, authority.getAuthority())){
                    System.out.println("拥有该权限!");
                    //拥有权限
                    return true;
                }
            }
            System.out.println("权限不足!");
        }
        return false;
    }
}

 2.10 配置鉴权方法,核心适配器

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .formLogin().loginPage("/tologin")
                    .loginProcessingUrl("/gologin")
                    .failureUrl("/tologin?error=1").permitAll()
                .and()
                .logout().permitAll()
                .and()
                .authorizeRequests()
            		//配置静态资源放行
                    .mvcMatchers("/static/**", "*.js", "*.css").permitAll()
            		//配置首页需要身份认证
                    .mvcMatchers("/").authenticated()
                    //配置其他所有请求需要通过自定义方法的鉴权
                    .anyRequest().access("@perssionHandler.hasPerssion(request, authentication)")
                .and()
                .csrf().disable()
            	//配置权限不足时抛出的url
                .exceptionHandling().accessDeniedPage("/noperssion");
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/325356.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号