java - 如何在 Spring Boot 中使用 RESTful 和基本身份验证
问题描述
您好,我正在使用带有基本身份验证的 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;
}
而且我有一个问题,例如我正在使用 Postman 来检索特定用户的目标,如下所示:
带有 GET 请求的http://localhost:8080/jpa/users/john/goals
然后我使用用户名 john 的基本身份验证和此用户名的密码,我收到了 john 的目标。
之后,如果我对此链接http://localhost:8080/jpa/users/tom/goals进行 GET 请求,我会收到 tom 的目标,但此时我已使用 john 登录,所以 john 可以看到他的目标,他也可以看到汤姆的目标。
问题是如何访问 RestController 中的登录用户名,因为我想做这样的事情:
if (loginUsername == username) {
return goalJpaRepository.findByUserId(userId);
}
return "Access denied!";
所以我想知道是否可以从 HTTP Header 访问登录用户名?
谢谢!
更新- 是的,框架是 Spring Boot,我也使用带有 Dao 身份验证的 Spring Security,因为我想从 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());
}
}
解决方案
假设您使用 Spring 作为 Java 框架,您应该使用 Spring 安全性来配置基本身份验证。在线提供许多教程(https://www.baeldung.com/spring-security-basic-authentication,
然后 Spring Security 将提供整个应用程序 ( SecurityContextHolder.getContext()
) 中可用的安全上下文,您可以从中检索连接的用户信息(用户名,...)。
例如,要检索连接用户的用户名,您应该这样做:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String loginUsername = authentication.getName();
或者,正如@gervais.b 所述,Spring 可以在您的控制器方法中注入Principal
(or )。Authentication
正如@Glains 所说,一个更好的选择是使用@PreAuthorize
and@PostAuthorize
注释,它允许您基于 Spring 表达式语言定义简单的规则。
推荐阅读
- scala - 将 Spark DataFrame 架构转换为新架构
- django - 如何在 Django 中实现两个具有彼此外键关系的抽象模型?
- java - 有没有办法对时间限制进行编码?
- python - 带有非默认 Visual Studio 的 cvxopt 自定义安装
- javascript - 字符串到 JSON 数组
- regex - python 正则表达式:如何提取 'A =BC= D' -> 'BC'
- javascript - 如何在 MongoDB 中将嵌套对象显示为超级对象?
- java - JPA:2个数组列表到1个数据库表中
- android - 如何将文件下载到Android中的内部下载文件夹中
- html - 更改 R Shiny textInput 指令的字体系列/大小/样式