如何在 Spring Boot 中使用 RESTful 和基本身份验证

elv*_*vis 5 java rest restful-authentication basic-authentication spring-rest

你好,我使用 RESTful 进行基本身份验证,此代码是 RestController 的一部分:

@GetMapping("/jpa/users/{username}/goals")
public List<Goal> getAllGoals(@PathVariable String username) {
    userId = getUserIdFromUsername(username);
    return goalJpaRepository.findByUserId(userId); 
}

public Long getUserIdFromUsername(String username) {
    User user = userJpaRepository.findByUsername(username);
    userId = user.getId(); 
    return userId;
}
Run Code Online (Sandbox Code Playgroud)

我有一个问题,例如我正在使用 Postman 来检索特定用户的目标,如下所示:

http://localhost:8080/jpa/users/john/goals 带有 GET 请求

然后我对用户名 john 和该用户名的密码使用基本身份验证,然后我收到了 john 的目标。

之后,如果我对此链接http://localhost:8080/jpa/users/tom/goals执行 GET 请求,我会收到 Tom 的目标,但此时我已使用 john 登录,因此 john 可以看到他的目标,他也可以看到汤姆的目标。

问题是我如何访问 RestController 中的登录用户名,因为我想做这样的事情:

if (loginUsername == username) {
    return goalJpaRepository.findByUserId(userId);
} 

return "Access denied!";
Run Code Online (Sandbox Code Playgroud)

所以我想知道是否可以从HTTP Header访问登录用户名?

谢谢你!


更新- 是的,框架是 Spring Boot,我也使用 Spring Security 和 Dao 身份验证,因为我想从 MySQL 数据库获取用户。无论如何,我不是 Spring Security 的专家。

现在我了解如何在我的控制器方法中使用Principal,但我不知道如何在这种特定情况下使用Spring Security。我应该如何实施?例如,用户 john 应该仅查看和修改他的目标。

春季安全配置:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import com.dgs.restful.webservices.goaltrackerservice.user.MyUserDetailsService;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private MyUserDetailsService userDetailsService;

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider
          = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userDetailsService);
        authProvider.setPasswordEncoder(bCryptPasswordEncoder());
        return authProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/allusers").permitAll()
                .anyRequest().authenticated()
                .and()
            // .formLogin().and()
            .httpBasic();
        }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvider());
    }
}
Run Code Online (Sandbox Code Playgroud)

ger*_*s.b 1

请注意,您目前没有执行任何安全措施。

正如@Matt 所说“这取决于您使用的框架”。但我猜你正在使用 spring。然后您应该查看 spring-securety 模块文档。

基本上,您可以将经过身份验证的用户注入到您的方法参数中:

   @GetMapping("/jpa/users/{username}/goals")
   public List<Goal> getAllGoals(@PathVariable String username, Principal principal) {
     if ( username.equals(principal.getName()) ) {
       userId = getUserIdFromUsername(username);
       return goalJpaRepository.findByUserId(userId); 
     } else {
       throw new SomeExceptionThatWillBeMapped();
     }
   } 
Run Code Online (Sandbox Code Playgroud)

但是 spring-security 和许多框架提供了更好的模式来管理安全性。