SpringBoot整合SpringSecurity
in 默认分类 with 0 comment 13 views

SpringBoot整合SpringSecurity

in 默认分类 with 0 comment 13 views

之前试过shiro作为权限框架,但毕竟SpringSecurity是Spring家族的成员,所以想试试用他来作为SpringBoot项目的权限框架。

环境

组件版本
JDK1.8
SpringBoot2.5.0

maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- swagger 3.0 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

项目里还需要用到mysql数据库存用户信息与权限信息,并且需要redis做权限信息缓存,简单起见这部分下面会用伪代码。
另外项目里还用到Swagger作为接口文档,后续需要放通swagger文档相关的路径权限,所以这里也顺便记录下。

整合部分

swagger

首先把swagger配置好,我用的是swagger 3.0版本,可以用springfox-boot-starter依赖进行导入,这里规定后续的token是通过header里的Authorization字段进行传送,所以需要给swagger配置全局的授权信息,配置文件如下:

@EnableOpenApi
@Configuration
public class SwaggerConfig implements WebMvcConfigurer {

    @Bean
    public Docket createRestApi() {
        //返回文档摘要信息
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo())
                .select()
                // 扫描注解
                //.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 扫描包
                .apis(RequestHandlerSelectors.basePackage("com.visionki.test.security.controller"))
                .paths(PathSelectors.any())
                .build()
                .groupName("测试接口")
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }

    /**
     * 生成接口信息,包括标题、联系人等
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Swagger3接口文档")
                .description("接口文档")
                .contact(new Contact("Vision", "", ""))
                .version("1.0")
                .build();
    }

    /**
     * 设置授权信息
     * @return
     */
    private List<SecurityScheme> securitySchemes() {
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", In.HEADER.toValue());
        return Collections.singletonList(apiKey);
    }

    /**
     * 授权信息全局应用
     * @return
     */
    private List<SecurityContext> securityContexts() {
        return Collections.singletonList(
                SecurityContext.builder()
                        .securityReferences(Collections.singletonList(new SecurityReference("Authorization", new AuthorizationScope[]{new AuthorizationScope("global", "")})))
                        .build()
        );
    }
}

SpringSecurity

自定义登陆逻辑需要实现org.springframework.security.core.userdetails.UserDetailsService里的loadUserByUsername方法,该方法主要的作用是根据前端传来的账号,去数据库匹配用户。返回一个org.springframework.security.core.userdetails.UserDetails类,简单起见我就用SpringSecurity自带的UserDetails实现类org.springframework.security.core.userdetails.User

@Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 这里需要查询数据库,简单起见写死
        // 三个参数,分别是:账号admin,密码MD5(123456),权限列表有index一个权限
        return new User("admin",
                "e10adc3949ba59abbe56e057f20f883e",
                Stream.of("index").map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
    }
}
Responses