Spring Security 在开发模式下自动对用户进行身份验证,无需询问凭据

ovfsdjhp  于 11个月前  发布在  Spring
关注(0)|答案(1)|浏览(168)

我有一个Spring REST API(我将其简化为一个最小的可复制示例),使用Spring Security进行保护,如下所示。
安全配置:

package com.example.demo;

// Imports...

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((requests) -> requests
                        .anyRequest().authenticated()
                )
                .formLogin((form) -> form
                        .loginPage("/login")
                        .permitAll()
                )
                .logout((logout) -> logout.permitAll());

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user =
                User.withDefaultPasswordEncoder()
                        .username("user")
                        .password("password")
                        .roles("USER")
                        .build();

        return new InMemoryUserDetailsManager(user);
    }
}

字符串
MVC配置:

package com.example.demo;

// Imports ...

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }

}


控制器代码:

@RestController
public class DemoController {
    @GetMapping("/")
    public String home (Authentication auth){
        return "Hello " + auth.getName();
    }
}


登录页面:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
    <title>Spring Security Example </title>
</head>
<body>
<div th:if="${param.error}">
    Invalid username and password.
</div>
<div th:if="${param.logout}">
    You have been logged out.
</div>
<form th:action="@{/login}" method="post">
    <div><label> User Name : <input type="text" name="username"/> </label></div>
    <div><label> Password: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>


我的build.gradle.kts

plugins {
    java
    id("org.springframework.boot") version "3.1.5"
    id("io.spring.dependency-management") version "1.1.3"
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
    mavenCentral()
}

dependencies {
    implementation ("org.springframework.boot:spring-boot-starter-web")
    implementation ("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation ("org.springframework.boot:spring-boot-starter-security")
    implementation ("org.thymeleaf.extras:thymeleaf-extras-springsecurity6:3.1.1.RELEASE")
    implementation ("org.springframework.security:spring-security-test")
    testImplementation ("org.springframework.boot:spring-boot-starter-test")
}

tasks.withType<Test> {
    useJUnitPlatform()
}

tasks.bootBuildImage {
    builder.set("paketobuildpacks/builder-jammy-base:latest")
}


我想实现的是在开发模式下对用户进行身份验证,而不必转到登录页面(向用户提供某些@Profile("dev")标记的组件中的代码)。在某种程度上,我的Controller代码不必更改。这可能吗?

gpfsuwkq

gpfsuwkq1#

这只是一个最小的例子:

package com.stackoverflow.question77536279;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
@Profile("dev")
public class AutoLoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

        var securityContext = SecurityContextHolder.getContext();
        if (securityContext.getAuthentication() != null && !securityContext.getAuthentication().isAuthenticated()) {
            securityContext.setAuthentication(
                    new UsernamePasswordAuthenticationToken(
                            "dev-user",
                            "dev-password",
                            Set.of(new SimpleGrantedAuthority("ADMIN"))
                    )
            );
        }
    }

}

字符串
这可以做到这一点,但如果您不将此类从生产构建中排除,任何可以修改启动参数的人都可以激活此组件,这是一个很大的安全漏洞。

相关问题