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

Spring Security:userDetailsService用户认证以及授权

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

Spring Security:userDetailsService用户认证以及授权

编写:Horin

文章目录
  • 前言
  • 一、导入框架依赖
  • 二、操作流程
    • 1.继承WebSecurityConfigurerAdapter并重写方法
    • 2.实现UserDetailsService接口
    • 3.编写数据持久化接口
    • 4.创建数据库
    • 5.Mapper映射文件
    • 6.编写实体类
    • 7.完善SecurityConfig配置:授权、自定义页面等
    • 8.登录页面修改为form表单提交
  • 总结


前言

Spring 安全性是提供认证、授权和防范常见攻击的框架。由于对imperative和reactive应用程序的安全都提供了第一类支持,因此它是保护基于 Spring 的应用程序的事实上的标准。

有关功能的完整列表,请参见引用的Features部分。
Spring安全 中文文档


提示:以下是本篇文章正文内容,下面案例可供参考

一、导入框架依赖

1、添加依赖:pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.7
         

    

    com.example
    TheToken
    0.0.1-SNAPSHOT
    TheToken
    TheToken
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.projectlombok
            lombok
            true
        
        
        
            org.springframework.boot
            spring-boot-devtools
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.2.0
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
        
        
        
            mysql
            mysql-connector-java
            runtime
        
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        
        
        
            org.springframework.boot
            spring-boot-starter-security
        
        
        
            org.thymeleaf.extras
            thymeleaf-extras-springsecurity5
        
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.6.7
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    



二、操作流程 1.继承WebSecurityConfigurerAdapter并重写方法

配置类:SecurityConfig.java

package com.example.thetoken.config;

import com.example.thetoken.service.serviceImpl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDeniedException;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;


@EnableWebSecurity  // 开启MVC security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;
    
    
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    

    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
        
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        
        
//        auth.inMemoryAuthentication().passwordEncoder(encoder)
//                .withUser("jsor").password(encoder.encode("12312333")).roles("common")
//                .and()
//                .withUser("wanglaoji").password(encoder.encode("123456")).roles("admin");

        
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }

}

2.实现UserDetailsService接口

实现类:UserDetailsServiceImpl.java

package com.example.thetoken.service.serviceImpl;

import com.example.thetoken.domain.User;
import com.example.thetoken.domain.Authority;
import com.example.thetoken.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;


@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        
        User user = userMapper.selectUser(s);
        List authorities = userMapper.selectAuths(s);

        
        List list = authorities.stream().map(
                authority -> new SimpleGrantedAuthority(authority.getAuthority())).collect(Collectors.toList());

        
        if(user!=null){
            System.out.println(user.getUserName()+"  "+user.getUserAccount()+"  "+user.getUserPassword());
            String userA = user.getUserAccount();
            String pasA = user.getUserPassword();
            System.out.println(list);
            //数据库为明文密码,所以使用对象来转换为需要的加密格式
            BCryptPasswordEncoder bCryptPasswordEncoder=new BCryptPasswordEncoder();
            UserDetails userDetails=
                    new org.springframework.security.core.userdetails.User(userA, bCryptPasswordEncoder.encode(pasA), list);
            System.out.println(userDetails);
            return userDetails;
        } else {

            
            return null;
        }
    }
}

3.编写数据持久化接口

实现类:UserMapper.java

package com.example.thetoken.mapper;


import com.example.thetoken.domain.Authority;
import com.example.thetoken.domain.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;


@Mapper
public interface UserMapper {
	
	//验证用户账号是否匹配
    User selectUser(String userAccount);
    
    //获取该用户名的权限
    List selectAuths(String userAccount);

}

4.创建数据库

SQL导出文件:springbootf.sql


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for authority
-- ----------------------------
DROP TABLE IF EXISTS `authority`;
CREATE TABLE `authority`  (
  `id` int(50) NOT NULL,
  `authority` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of authority
-- ----------------------------
INSERT INTO `authority` VALUES (1, 'ROLE_admin');
INSERT INTO `authority` VALUES (2, 'ROLE_common');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `user_id` int(5) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `user_account` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `user_password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `sex` int(1) NOT NULL COMMENT '0-女,1-男',
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '江治雨', '8823', 'j12312333', 1);
INSERT INTO `user` VALUES (2, '周杰伦', '123', '123', 1);
INSERT INTO `user` VALUES (4, '邓丽君', 'dengli312884', '987654321', 0);
INSERT INTO `user` VALUES (6, '张国荣', '401', 'zgr', 1);
INSERT INTO `user` VALUES (7, 's', 's', '', 1);

-- ----------------------------
-- Table structure for user_authority
-- ----------------------------
DROP TABLE IF EXISTS `user_authority`;
CREATE TABLE `user_authority`  (
  `id` int(20) NOT NULL,
  `user_id` int(50) NOT NULL,
  `authority_id` int(50) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user_authority
-- ----------------------------
INSERT INTO `user_authority` VALUES (1, 1, 1);
INSERT INTO `user_authority` VALUES (2, 2, 2);

SET FOREIGN_KEY_CHECKS = 1;


5.Mapper映射文件

映射文件:UserMapper.xml





    
        
        
        
        
        
    
    
    
        select a.* from user c, authority a, user_authority ca
                   where
                       ca.user_id=c.user_id and ca.authority_id=a.id and c.user_account =#{userAccount}
    
    



6.编写实体类

省略:User实体类、Authority实体类


7.完善SecurityConfig配置:授权、自定义页面等

配置类:SecurityConfig.java

package com.example.thetoken.config;

import com.example.thetoken.service.serviceImpl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDeniedException;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;


@EnableWebSecurity  // 开启MVC security安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        super.configure(http);
        
        http.authorizeRequests()
                // 静态资源、登录、注册页面放行
               .antMatchers("/login
        http.formLogin()
                //跳转登陆页面接口
                .loginPage("/toLogin")
                //以下Controller接口无需编写
                .loginProcessingUrl("/loginss")
                //主页面接口
                .defaultSuccessUrl("/");

        
        http.rememberMe()
                .rememberMeParameter("rememberme")
                .tokenValiditySeconds(2000);
                // 对cookie信息进行持久化管理
               // .tokenRepository(tokenRepository());

        
        http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
                // 如果是权限访问异常,则进行拦截到指定错误页面
                RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher("/err");
                dispatcher.forward(httpServletRequest, httpServletResponse);
            }
        });
    }
    
    @Bean
    public JdbcTokenRepositoryImpl tokenRepository(){
        JdbcTokenRepositoryImpl jr=new JdbcTokenRepositoryImpl();
        jr.setDataSource(dataSource);
        jr.setCreateTableOnStartup(false);
        return jr;
    }

    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        
//        auth.inMemoryAuthentication().passwordEncoder(encoder)
//                .withUser("jsor").password(encoder.encode("12312333")).roles("common")
//                .and()
//                .withUser("wanglaoji").password(encoder.encode("123456")).roles("admin");

        
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }

}

8.登录页面修改为form表单提交

登录页面:https://blog.csdn.net/horinjsor/article/details/index.html

注意事项:仅供参考结构,未上传css样式文件。
重点一,input的name属性必须固定,账号为username,密码为password。
重点二,form标签的action与配置类中的登录接口一样,spring会自动创建。



  
  欢迎登录
  
  
  
  
  
  
  
  






总结

其中HTML页面、Controller跳转补充完成,就可以正常运行了。

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

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

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