spring security

spring boot 之 security(一) 配置

2019-10-12  本文已影响0人  _大叔_

我这里使用的是多项目搭建,we和app是分开的

项目结构

项目结构

一、先引入依赖

core 中的依赖

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>

        <!-- 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 第三方对接 依赖包QQ,微信等 -->
        <!-- 提供Java 配置  -->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-config</artifactId>
            <version>1.1.4.RELEASE</version>
        </dependency>
        <!-- 提供社交连接框架和OAuth 客户端支持 -->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-core</artifactId>
            <version>1.1.4.RELEASE</version>
        </dependency>
        <!-- 提供社交安全支持 -->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-security</artifactId>
            <version>1.1.4.RELEASE</version>
        </dependency>
        <!-- 管理web应用程序的连接 -->
        <dependency>
            <groupId>org.springframework.social</groupId>
            <artifactId>spring-social-web</artifactId>
            <version>1.1.4.RELEASE</version>
        </dependency>

        <!-- oauth2协议 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

web 中的依赖

        <dependency>
            <groupId>com.wt</groupId>
            <artifactId>security-core</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session</artifactId>
            <version>1.3.1.RELEASE</version>
        </dependency>

app 中的依赖

        <dependency>
            <groupId>com.wt</groupId>
            <artifactId>security-core</artifactId>
            <version>${project.version}</version>
        </dependency>

demo 中的依赖

        <dependency>
            <groupId>com.wt</groupId>
            <artifactId>security-web</artifactId>
            <version>${project-version}</version>
        </dependency>

二、配置文件

demo 中的配置

server:
  port: 9203

# jdbc_config   datasource
spring:

  application:
    name: security-demo

  # 指定session集群的存储,启动之前这里先设置none要不然redis和jdbc会报覆盖类错误。
  session:
    store-type: none

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.15.128:3306/cloud?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: password
    # Hikari will use the above plus the following to setup connection pooling
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 5
      maximum-pool-size: 15
      auto-commit: true
      idle-timeout: 30000
      pool-name: DatebookHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
      connection-test-query: SELECT 1

#  redis:
#    database: 0
#    host: 192.168.15.128
#    port: 6379
#    password:
#    lettuce:
#      pool:
#        max-active: 20
#    timeout: 5000

三、security中的核心及原理

核心过滤器

spring security 最主要的核心就是过滤器,他先会从 绿色 部分开始执行,到 橘色 进行校验,如果校验失败,则会返回到 蓝色Exception 部分。
以上图中的这几个Filter大家可以在idea中找到并得到源码,执行最简单的debug来查看。
若想要 UsernamePasswordAuthenticationFilter 生效,则需要一个类继承WebSecurityConfigurerAdapter 并重写configure(HttpSecurity http),否则走默认配置(Basic)。


配置WebSecurityConfigurerAdapter

四、简单定制自己的身份认证

一开始默认的是spring自己的身份认证,在启动后控制台会给一个密码用于最基本的登陆认证,如果我想自定义一个账号密码怎么办?接下来介绍的是 UserDetailsService,这是spring自带的负责用户信息获取的一个接口,我们只要重写 loadUserByUsername 这个方法即可。

package com.wt.cloud.service;

import lombok.extern.slf4j.Slf4j;
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.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.*;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;


@Component
@Slf4j
/**
 * 功能描述: UserDetailsService负责用户信息获取逻辑
 * @author : big uncle
 * @date : 2019/10/11 15:21
 */
public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        log.info("登陆用户名称:{}",s);
        String password = "123456";
        log.info("获得密码:{}",password);
        // UserDetails 处理用户校验逻辑
        UserDetails userDetails = User.builder()
                .username(s)
                // 当你在密码123456上使用了前缀{noop} 意味着你的密码不使用加密
                .password(password)
                // 解码
                .passwordEncoder((str) -> "{bcrypt}" + new BCryptPasswordEncoder().encode(str))
//                // 账号是否过期 如果帐户已过期,则为true,否则为false
                .accountExpired(false)
//                // 账号是否被锁 如果帐户已锁定,则为true,否则为false
                .accountLocked(false)
//                // 账号是否可用 如果帐户被禁用,则为true,否则为false
                .disabled(false)
//                // 凭证是否过期 如果凭据已过期,则为true,否则为false
                .credentialsExpired(false)
                // 权限
                .authorities( AuthorityUtils.commaSeparatedStringToAuthorityList("admin"))
                .build();
        return userDetails;
    }

    /**
     * 功能描述: 列出所有的加密方式
     * @author : big uncle
     * @date : 2019/10/12 0:11
     */
    public static Map<String,PasswordEncoder> encoders(){
        return new HashMap<String,PasswordEncoder>(){{
            put("bcrypt", new BCryptPasswordEncoder());
            // 不做加密
            put("noop", NoOpPasswordEncoder.getInstance());
            put("pbkdf2", new Pbkdf2PasswordEncoder());
            put("scrypt", new SCryptPasswordEncoder());
            put("sha256", new StandardPasswordEncoder());
        }};
    }

}
或把加密方式写到配置里
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

@Slf4j
@Component
public class MyUserDetails implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        log.debug("登陆账号是 {}",s);
        String password = "123455";
        String newPassword = passwordEncoder.encode(password);
        log.debug("加密后的密码是 {}",newPassword);
        return new User(s,newPassword,true,true,true,true, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }
}

上一篇 下一篇

猜你喜欢

热点阅读