【发布时间】:2021-09-04 22:24:56
【问题描述】:
我有一个带有 mongo 数据库和 spring security 作为依赖项的 spring boot 应用程序。 它有两个服务,第一个用于身份验证,第二个用于应用程序资源(实体、服务控制器)。 这是我在身份验证服务中的配置类:
@Configuration
@EnableWebSecurity
public class AuthServerSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean
protected UserDetailsService userDetailsService() {
return new MongoUserDetailsService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().anyRequest().authenticated();
System.out.println("auth");
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Bean(name="authenticationManager")
@Lazy
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
这是其余控制器:
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping(value = "/api/users")
public class UserController {
@Autowired
UserServiceImpl userServiceImpl;
//Getting all users
@GetMapping(value = "")
public List<UserDTO> getAllUsers() {
return userServiceImpl.getAllUsers();
}
//Getting a user by ID
@GetMapping(value = "/profil/{userId}")
public UserDTO getUserById(@PathVariable String userId) {
return userServiceImpl.getUserById(userId);
}
//Getting a user by Username
@GetMapping(value = "/profil/username/{username}")
public UserDTO getUserByUsernameOrEmail(String username) {
return userServiceImpl.getUserByUsernameOrEmail(username);
}
//Logout user and delete token
@PostMapping("/logout")
public void logout(HttpServletRequest request) {
userServiceImpl.logout(request);
}
我将配置方法更改为:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests() // authorize
.anyRequest().authenticated() // all requests are authenticated
.and()
.httpBasic();
http.cors();
}
现在我在访问受保护资源时得到 401 未授权。问题是现在即使我在请求标头中发送正确的不记名令牌,我仍然得到 401 未授权“访问此资源需要完全身份验证”
更新: 我将项目架构从微服务更改为一个简单的 Spring Boot 项目。 这是“AuthServerSecurityConfig”类的新代码
@Configuration
public class AuthServerSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean
protected UserDetailsService userDetailsService() {
return new MongoUserDetailsService();
}
@Autowired
BCryptPasswordEncoder passwordEncoder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//auth.userDetailsService(userDetailsService());
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.anonymous().disable()
.authorizeRequests()
.antMatchers("/oauth/token").permitAll().and()
.httpBasic();
http.cors();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Bean(name="authenticationManager")
@Lazy
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
还有这个“ResourceServerConfig”代码:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Autowired private ResourceServerTokenServices tokenServices;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("foo").tokenServices(tokenServices);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() // authorize
.antMatchers("/oauth/**").permitAll();
http
.authorizeRequests().antMatchers("/api/**").authenticated();
http
.headers().addHeaderWriter(new HeaderWriter() {
@Override
public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getMethod().equals("OPTIONS")) {
response.setHeader("Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method"));
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
}
}
});
}
}
当我尝试访问受保护的资源时,我得到“错误”:“未经授权”, “error_description”:“访问此资源需要完全身份验证”,这是正常行为。问题是现在我无法登录以获取用户 aceess_token。
访问此端点“http://localhost:8080/oauth/token?grant_type=password&username=user&password=user”时,我得到“401 未授权”。
这些是默认的 init 用户凭据,该用户存在于我的 mongodatabase 中,密码格式正确且加密,密码以“$2a”开头,包含“60”个字符。
我进入“编码密码看起来不像 BCrypt 身份验证失败:尝试登录时,控制台中的密码与存储的值不匹配。
【问题讨论】:
-
你的休息控制器里有什么?有
@PreAuthorize注释吗? -
我有一个 @PreAuthorize 注释,但在我试图访问的其余控制器上没有:我更新了我的问题!!
-
您在哪个端点上得到 403 响应?您是否有可以正常工作的端点?请与调试分享完整的堆栈错误
-
在“api/users”上。当我删除“.authorizeRequests().anyRequest().authenticated()”时它们工作正常
-
您是否对这些请求使用经过身份验证的会话?
标签: mongodb spring-boot spring-security spring-security-oauth2