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

spring security入门

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

spring security入门

文章目录
  • 1 入门案例
    • 1.1 引入依赖
    • 1.2 web配置
    • 1.3 security配置
    • 1.4 查询用户
    • 1.5 登录页面
  • 2 过滤器
  • 3 页面动态展示
  • 4 权限控制
    • 4.1 开启注解支持
    • 4.2 添加注解
    • 4.3 友好页面展示
      • 4.3.1 security配置文件设置
      • 4.3.2 web配置文件设置
      • 4.3.3 异常处理器

Spring Security基于servlet过滤器实现的权限管理框架,是AOP思想的具体体现,提供了完善的认证机制和方法级的授权功能。本文基于springmvc项目。

1 入门案例

查询数据库用户信息,实现登录认证。

1.1 引入依赖

    org.springframework.security
    spring-security-config
    5.3.1.RELEASE


    org.springframework.security
    spring-security-taglibs
    5.3.1.RELEASE

1.2 web配置

web.xml



     
         dispatcherServlet
         org.springframework.web.servlet.DispatcherServlet
         
             contextConfigLocation
             
             classpath:applicationContext.xml
         
         1
     
     
         dispatcherServlet
         /
     
     
     
         characterEncodingFilter
         org.springframework.web.filter.CharacterEncodingFilter
         
             encoding
             UTF-8
         
     
     
         characterEncodingFilter
         /*
     
    
    
        springSecurityFilterChain
        org.springframework.web.filter.DelegatingFilterProxy
    
    
        springSecurityFilterChain
        /*
    

1.3 security配置

创建spring-security.xml文件:



    
    
    
    
    

    
    
        
        
        
        
        
        
        
        
        
        
    
    
    
        
        
            
            
                
                
            

            
            
            
        
    

主配置文件applicationContext.xml中引入spring-security.xml,创建加密对象(用于密码加密保存和加密认证):




1.4 查询用户

userService实现:

@Service("userService")
public class UserServiceImp implements UserService {

    @Resource
    private UserDao userDao;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;

    public List selectAll() {
        return userDao.findAll();
    }

    public void addUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));//加密存储
        userDao.addUser(user);
    }

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        List users = userDao.findByUserName(username);
        if(users == null || users.size() == 0){
            throw new UsernameNotFoundException(String.format("JdbcDaoImpl.notFound %s",username));
        }
        User user = users.get(0);
        List grantedAuthorities = new ArrayList<>();
        for(Role role : user.getRoles()){
            grantedAuthorities.add(new SimpleGrantedAuthority(role.getRoleName()));
        }
        //密码前拼接"{noop}",表示密码不加密验证,不加,需要加密验证
        //本地项目中的User类和spring security中的冲突了,直接带包名创建
        return new org.springframework.security.core.userdetails.User(user.getUserName(),user.getPassword(),user.getStatus()==1,true,true,true,grantedAuthorities) ;
    }

    public void updateUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        userDao.updateUser(user);
    }
}

要事先准备好用户表、角色表、权限表、用户角色表、角色权限表,并添加一些数据。

--先删除关联表
DROP TABLE IF EXISTS `SYS_ROLE_PERMISSION`;
DROP TABLE IF EXISTS `SYS_USER_ROLE`;

DROP TABLE IF EXISTS `SYS_USER`;
CREATE TABLE `SYS_USER` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT,
  `USER_NAME` VARCHAR(32) NOT NULL COMMENT '用户名称',
  `PASSWORD` VARCHAR(120) CHARACTER SET UTF8 COLLATE UTF8_GENERAL_CI NOT NULL COMMENT '密码',
  `STATUS` INT(1) DEFAULT '1' COMMENT '1有效,0无效',
  PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

DROP TABLE IF EXISTS `SYS_ROLE`;

CREATE TABLE `SYS_ROLE` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `ROLE_NAME` VARCHAR(30) DEFAULT NULL COMMENT '角色名称',
  `ROLE_DESC` VARCHAR(60) DEFAULT NULL COMMENT '角色描述',
  PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

CREATE TABLE `SYS_USER_ROLE` (
  `UID` INT(11) NOT NULL COMMENT '用户编号',
  `RID` INT(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY (`UID`,`RID`),
  CONSTRAINT `FK_REFERENCE_1` FOREIGN KEY (`RID`) REFERENCES `SYS_ROLE` (`ID`),
  CONSTRAINT `FK_REFERENCE_2` FOREIGN KEY (`UID`) REFERENCES `SYS_USER` (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

DROP TABLE IF EXISTS `SYS_PERMISSION`;
CREATE TABLE `SYS_PERMISSION` (
  `ID` INT(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `PERMISSION_NAME` VARCHAR(30) DEFAULT NULL COMMENT '菜单名称',
  `PERMISSION_URL` VARCHAR(100) DEFAULT NULL COMMENT '菜单地址',
  `PARENT_ID` INT(11) NOT NULL DEFAULT '0' COMMENT '父菜单ID',
   PRIMARY KEY (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

CREATE TABLE `SYS_ROLE_PERMISSION` (
  `RID` INT(11) NOT NULL COMMENT '角色编号',
  `PID` INT(11) NOT NULL COMMENT '权限编号',
  PRIMARY KEY (`RID`,`PID`),
  CONSTRAINT `FK_REFERENCE_3` FOREIGN KEY (`RID`) REFERENCES `SYS_ROLE` (`ID`),
  CONSTRAINT `FK_REFERENCE_4` FOREIGN KEY (`PID`) REFERENCES `SYS_PERMISSION` (`ID`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
1.5 登录页面

login.jsp页面中添加标签库,表单标签下添加标签

<%@taglib prefix="security" uri="http://www.springframework.org/security/tags"%>

还需要写个login之后的跳转Controller,最后启动tomcat,进行登录验证。

“记住我”功能补充说明:
将用户名密码和token都存在客户端相对不安全,另一种方法是在cookie中仅保存一个无意义的加密串,在数据库中保存加密串与登录用户(用户名、密码、token、时间)的对应关系,下次自动登录时,cookie中的加密串与数据库中的数据一同进行验证。
添加存储表PERSISTENT_LOGINS:

CREATE TABLE `PERSISTENT_LOGINS` ( 
     `SERIES` VARCHAR(64) NOT NULL, 
     `USERNAME` VARCHAR(64) NOT NULL, 
     `TOKEN` VARCHAR(64) NOT NULL, 
     `LAST_USED` TIMESTAMP NOT NULL, 
      PRIMARY KEY (`SERIES`)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;

spring-security.xml中:


2 过滤器

spring security的核心是过滤器,一系列过滤器组成了过滤器链,如下图:

序号过滤器说明
1SecurityContextPersistenceFilter使用SecurityContextRepository在session中保存或更新一个 SecurityContext,并将SecurityContext给过滤器链中之后的过滤器使用。 SecurityContext中存储了当前用户的认证以及权限信息。
2WebAsyncManagerIntegrationFilter用于集成SecurityContext到Spring异步执行机制中的WebAsyncManager。
3HeaderWriterFilter向请求的Header中添加信息,可在标签内部使用来控制
4CsrfFilter跨域请求伪造过滤,对所有post请求验证是否包含系统生成的csrf的token信息, 如果不包含,则报错。可防止csrf攻击。可设置禁用,如果为开启,则必须为post请求。
5LogoutFilter匹配URL为/logout的请求,实现用户退出,清除认证信息。
6UsernamePasswordAuthenticationFilter主要负责认证的过滤器,默认匹配URL为/login且必须为POST请求。
7DefaultLoginPageGeneratingFilter如果没有在配置文件中指定认证页面,则由该过滤器生成一个默认认证页面。
8DefaultLogoutPageGeneratingFilter生成一个默认的退出登录页面
9BasicAuthenticationFilter自动解析HTTP请求中头部名字为Authentication,且以Basic开头的头信息。
10RequestCacheAwareFilter通过HttpSessionRequestCache内部维护了一个RequestCache,用于缓存HttpServletRequest
11SecurityContextHolderAwareRequestFilter针对ServletRequest进行了一次包装,使得request具有更加丰富的API
12AnonymousAuthenticationFilter当SecurityContextHolder中认证信息为空,则会创建一个匿名用户存入到SecurityContextHolder中。为了兼容未登录的访问,也走了一套认证流程,只不过是一个匿名的身份。
13SessionManagementFilterSecurityContextRepository限制同一用户开启多个会话的数量
14ExceptionTranslationFilter异常转换过滤器,用来转换整个链中出现的异常
15FilterSecurityInterceptor获取所配置资源访问的授权信息,根据SecurityContextHolder中存储的用户信息来判断其是否有权限。
3 页面动态展示
标签说明
页面中某些内容需要根据角色显示时,用包裹
显示用户名,property属性值也可以为name
4 权限控制

通过注解的方式来控制类或者方法的访问权限。

4.1 开启注解支持

application.xml或者spring-mvc.xml中添加配置:


4.2 添加注解

Controller或者Service类或者方法上添加注解:

注解说明
@Secured({“ROLE_ADMIN”,“ROLE_USER”})security的注解,有ROLE_ADMIN或ROLE_USER角色才能访问
@RolesAllowed({“ROLE_ADMIN”,“ROLE_USER”})jsr250的注解
@PreAuthorize(“hasAnyRole(‘ROLE_ADMIN’,‘ROLE_USER’)”)spring的注解
4.3 友好页面展示

禁止访问时,友好页面展示的方式:

4.3.1 security配置文件设置

spring-security.xml中下添加:


4.3.2 web配置文件设置

web.xml中添加:


    403
    /errors/403.jsp

4.3.3 异常处理器
@ControllerAdvice
public class ControllerException {

    @ExceptionHandler(AccessDeniedException.class)
    public String exception403Advice(){
        return"redirect:/errors/403.jsp";
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/691837.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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