springSecruity自定义用户认证逻辑

1. 创建项目

使用idea中的spring 初始化工具引入springbootspringsecruity初始化项目

最终pom.xml如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo-spring-secruity</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo-spring-secruity</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

创建一个测试控制器

package com.example.demospringsecruity.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author john
 * @date 2020/1/6 - 9:47
 */
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello spring secruity";
    }
}

运行项目

访问<http://localhost:8081/hello>,会被跳转到<http://localhost:8081/login>

输入用户名user和刚才运行项目时输出的密码,登录成功,可以获取到刚才预期的响应

2. 自定义登录方式

package com.example.demospringsecruity.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author john
 * @date 2020/1/6 - 10:07
 */
@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 表单登录
//        http.formLogin()
        //  基本登录
        http.httpBasic()
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();
    }
}

当浏览器发送一个请求后,首先会经过第一个过滤器,UsernamePassowordAuthenticationFilter,这个过滤器中,它会判断你的请求是否带usernamepassword这两个参数,如果带了就进行拦截验证,如果没有就进入到第二个过滤器BasicAuthenticationFilter,这个过滤器会判断请求头中是否含有需要验证的信息,如果没有进入下一个拦截器,最后到ExceptionTranslationFilter拦截器,它会捕获FilterSecurityInterceptor抛出的异常,而FilterSecurityInterceptor会判断这个请求是否校验通过,权限是否通过,以上就是Spring Security框架的一个基本认证流程,FilterSecurityInterceptor是这个框架的最后一个拦截器,所有的请求都必须通过该拦截器的校验。

3. 自定义用户认证逻辑

1. 处理用户信息获取逻辑        UserDetailsService
2. 处理用户校验逻辑           UserDetails
3. 处理密码加密解密           PasswordEncoder

UserDetailsService

用户信息获取逻辑在springsecruity中是被封装在UserDetailService接口中

package org.springframework.security.core.userdetails;

public interface UserDetailsService {
    UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}

UserDetails

public interface UserDetails extends Serializable {
    Collection<? extends GrantedAuthority> getAuthorities();//权限的集合
    String getPassword();//密码
    String getUsername();//用户名
    boolean isAccountNonExpired();//账户是否没过期 true-->没过期
    boolean isAccountNonLocked();//账户是否没锁定 true-->没被锁定
    boolean isCredentialsNonExpired();//凭证是否没过期 true-->没过期
    boolean isEnabled();//账户是否可用
}

下面开始编写具体代码
MyUserDetailsService处理用户信息获取逻辑

package com.example.demospringsecruity.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
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.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author john
 * @date 2020/1/6 - 10:32
 */
@Component
@Slf4j
public class MyUserDetailsService implements UserDetailsService {
    //这里可以注入mapper或者repository的dao对象来实现数据校验逻辑操作
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("用户名:" + username);
        //这里密码应该从数据库中取出,暂时先使用加密生成
        String password = passwordEncoder.encode("123456");
        //User类是Spring内置的一个类,实现了UserDetails接口,而这个接口是UserDetailSerice的子接口
        return new User(username,
                password,
                true,        // 账户是否可用
                true,        // 账户是否过期
                true,        // 密码是否过期
                true,        //账户是否被锁定
                AuthorityUtils.commaSeparatedStringToAuthorityList("admin") //授权集合
        );
    }
}

PasswordConfig处理密码加密解密
注入PasswordEncoder

package com.example.demospringsecruity.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author john
 * @date 2020/1/6 - 12:51
 */
//说明这个一个配置类,类似spring中的xml文件
@Configuration
public class PasswordConfig {

    //手动将PasswordEncoder注入到ioc容器中
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

测试在输入用户user密码123456后成功获取数据

上面的演示我使用了spring-security自己的UserDetails实现类User(org.springframework.security.core.userdetails.User),但实际开发中我们不可能这么用,因为根据实际的业务,往往会希望用户信息表里会包含更多的数据,比如说电话,邮箱,公司职位等信息,那我们该如何去处理呢?

其实非常简单,我们只要将我们自己的User表继承spring-securityUser类(org.springframework.security.core.userdetails.User),再在MyUserDetailsService里只要返回我们自己的user即可.

原文地址:https://www.cnblogs.com/ifme/p/12155796.html

时间: 2024-08-29 14:43:59

springSecruity自定义用户认证逻辑的相关文章

在spring security手动 自定义 用户认证 SecurityContextHolder

1.Spring Security 目前支持认证一体化如下认证技术: HTTP BASIC authentication headers (一个基于IEFT  RFC 的标准) HTTP Digest authentication headers (一个基于IEFT  RFC 的标准) HTTP X.509 client certificate exchange  (一个基于IEFT RFC 的标准) LDAP (一个非常常见的跨平台认证需要做法,特别是在大环境) Form-based auth

Django 自定义用户认证

Django 自定义用户认证 Django附带的认证对于大多数常见情况来说已经足够了,但是如何在 Django 中使用自定义的数据表进行用户认证,有一种较为笨蛋的办法就是自定义好数据表后,使用OnetoOne来跟 Django 的表进行关联,类似于这样: from django.contrib.auth.models import User class UserProfile(models.Model): """ 用户账号表 """ user =

西游之路——python全栈——自定义用户认证

django自定义用户认证(使用自定义的UserProfile,而不是django自带的),就需要(django要求)将为UserProfile单独创建一个app,这个app啥也不干,就是为UserProfile而生的; 这里我们创建一个app,名字叫做custom_auth,事实上,我们只需要对其中的models文件和admin.py做操作就可以了; 第一步:  创建user model 下面是models.py文件的内容: 1 from django.utils.safestring imp

Spring Security自定义用户认证

具体代码地址 https://gitee.com/chuzhuyong/HandleSafer 自定义用户认证 通过自定义WebSecurityConfigurerAdapter类型的Bean组件,并重写configure(Authentication ManagerBuilder auth)方法, 可以实现自定义用户认证. 一.内存身份认证   In-Memory Authentication(内存身份认证)是最简单的身份认证方式,主要用于Security安全认证体验和测试 1.自定义WebS

Django自定义用户认证

自定义一个用户认证 详细参考官方文档: https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#django.contrib.auth.models.PermissionsMixin.has_perms 一.创建用户的表 UserProfile():存放用户信息的表 UserProfileManager(): 用户创建用户的类方法 1.生成一个单独的Moel文件专门用来存放用户表 #!/usr/bin/env python #

自定义用户认证(继承django的)

1.在app下创建一个自己用户认证文件,文件名随意,记得为.py文件 2.编辑该userauth.py文件 1 #!/usr/bin/env python 2 #coding:utf-8 3 from django.db import models 4 from django.contrib.auth.models import ( 5 BaseUserManager, AbstractBaseUser 6 ) 7 import django 8 9 class UserManager(Base

DRF自定义用户认证

一.settings中配置 AUTHENTICATION_BACKENDS = ( 'users.views.CustomBackend', ) 二.users/views.py # users.views.py from django.contrib.auth.backends import ModelBackend from django.contrib.auth import get_user_model from django.db.models import Q User = get_

02 spring security 自定义用户认证流程

1. 自定义登录页面 (1)首先在static目录下面创建login.html       注意: springboot项目默认可以访问resources/resources, resources/staic, resources/public目录下面的静态文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录页

Django自定义用户认证系统Customizing authentication

扩展已有的用户模型Extending the existing User model 有两种方法来扩展默认的User Model而不用重写自己的模型.如果你不需要改变存储在数据库中的字段,而只是需要改变Model的行为,您可以创建一个基于User的代理Model.允许的行为包括默认的ordering,custom managers, 或者 custom model methods. 如果你想存储与User有关的信息,可以使用一个OneToOneField字段关联到一个存储额外信息的Model.这