2

默认配置

所谓默认配置, 就是对Spring Security不做任何配置. 让它的自动配置起作用. 目的是对Spring Security 的默认行为有一个初步的直观的了解.

第一步: 使用Intellj IDEASpring Initializr 创建项目

clipboard.png

clipboard.png

clipboard.png

项目创建完成会自动生成一个应用入口类

package com.example.demowebfluxsecurityinmemory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoWebfluxSecurityInMemoryApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoWebfluxSecurityInMemoryApplication.class, args);
    }
}

第二步: 创建一个控制器

package com.example.demowebfluxsecurityinmemory;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.security.Principal;
import java.util.Collections;
import java.util.Map;

@RestController
public class UserController {
    @GetMapping("/")
    public Mono<Map<String, String>> hello(Mono<Principal> principal) {
        return principal
            .map(Principal::getName)
            .map(this::helloMessage);
    }

    private Map<String, String> helloMessage(String username) {
        return Collections.singletonMap("message", "Hello " + username + "!");
    }
}

mvn spring-boot:run 启动, 会在控制台输出中看到一个水机生成的UUID格式的密码:

clipboard.png

最后, 打开 http://localhost:8080/login 即可显示登录页面, 默认用户名称为 user. 到这里, Spring Security 的默认设置的样子就是这样的, 现实场景中是不可能这么简单的. 因此我们需要对它进行定制

定制

自定义配置(自定义用户账号)

添加一个配置类, 如下:

package com.example.demowebfluxsecurityinmemory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

@Configuration
public class SecurityConfig {
    @Bean
    public MapReactiveUserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("user")
            .roles("USER")
            .build();
        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("admin")
            .roles("ADMIN")
            .build();
        return new MapReactiveUserDetailsService(user, admin);
    }
}

现在重启服务器, 就可以使用自定义的用户名和密码登录了.

ReactiveUserDetailsService 是Webflux Security的一个核心接口, 代表了Spring Security 安全体系中的用户信息, 它只有一个接口方法Mono<UserDetails> findByUsername(String username);

作用: 该接口方法的作用是从各种存储中获取用户信息. 通过该接口拿到了用户的信息, 就可以通过判断用户的状态进行认证, 授权等操作.

这个接口的作用就一个: 获取 UserDetails 对象.

package org.springframework.security.core.userdetails;
import reactor.core.publisher.Mono;
public interface ReactiveUserDetailsService {
    Mono<UserDetails> findByUsername(String username);
}

MapReactiveUserDetailsService 实现了 UserDetailsService 接口, 其 findByUsername 方法是从一个 Map 中去获取 UserDetails 对象. 因此能够管理多个 UserDetails 对象.

其实现代码为:

@Override
public Mono<UserDetails> findByUsername(String username) {
    String key = getKey(username);
    UserDetails result = users.get(key);
    return result == null ? Mono.empty() : Mono.just(User.withUserDetails(result).build());
}

developerworks
1.7k 声望266 粉丝