具有两个身份验证的Spring boot应用。 AuthenticationManager bean问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有两个身份验证的Spring boot应用。 AuthenticationManager bean问题相关的知识,希望对你有一定的参考价值。
我需要具有两个不同登录/注册端点的Spring Boot应用,其中一个是api / user / auth / registerUser和api / node / auth / registerNode。
我编写了代码,但是现在我有两个authenticationManagerBean,请参阅配置:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {
@Configuration
@Order(1)
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {
@Autowired
CustomUserDetailsService customUserDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}
@Bean("authenticationManager")
@Qualifier("authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/user/auth/**")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
}
@Configuration
@Order(2)
public class SecurityConfig2 extends WebSecurityConfigurerAdapter {
@Autowired
CustomUser1DetailsService customUser1DetailsService;
@Autowired
private JwtAuthenticationEntryPoint1 unauthorizedHandler1;
@Bean
public JwtAuthenticationFilter1 jwtAuthenticationFilter1() {
return new JwtAuthenticationFilter1();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder1) throws Exception {
authenticationManagerBuilder1
.userDetailsService(customUser1DetailsService)
.passwordEncoder(passwordEncoder1());
}
@Bean("authenticationManager1")
@Qualifier("authenticationManager1")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder1() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler1)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/node/auth/**")
.permitAll()
.anyRequest()
.authenticated();
// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter1(), UsernamePasswordAuthenticationFilter.class);
}
}
}
并且我让用户控制:
@RestController
@RequestMapping("/api/user/auth")
public class UserAuthController {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
@Qualifier("authenticationManager")
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenProvider tokenProvider;
public UserAuthController() {
}
@PostMapping(path = "/registerUser")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
return new ResponseEntity(new ApiResponse(false, "Email Address already taken"), HttpStatus.BAD_REQUEST);
}
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return new ResponseEntity(new ApiResponse(false, "Username already taken"), HttpStatus.BAD_REQUEST);
}
// Creating User
User user = new User(signUpRequest.getUsername(), signUpRequest.getEmail(), passwordEncoder.encode(signUpRequest.getPassword()),
signUpRequest.getFirstName(), signUpRequest.getMiddleName(), signUpRequest.getLastName());
// Role userRole = roleRepo.findByName(RoleName.ROLE_USER)
// .orElseThrow(() -> new AppException("User Role not set."));
//
// Role adminRole = roleRepo.findByName(RoleName.ROLE_ADMIN)
// .orElseThrow(() -> new AppException("User Role not set."));
//
// Set<Role> rules = new HashSet<>();
// rules.add(userRole);
// rules.add(adminRole);
// user.setRoles(rules);
User result = userRepository.save(user);
return ResponseEntity.ok(result);
}
@PostMapping("/authenticateUser")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
try {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String accessToken = tokenProvider.generateAccessToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(accessToken,tokenProvider.getIssuedDateFromAccessToken(accessToken),tokenProvider.getExpirationDateFromAccessToken(accessToken)));
} catch (BadCredentialsException exception) {
throw new BadRequestException("Wrong username or password!");
}
}
}
和节点控制器:
@RestController
@RequestMapping("/api/node/auth")
public class NodeAuthController {
@Autowired
private User1Repository user1Repository;
@Autowired
private Role1Repository role1Repository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
@Qualifier("authenticationManager1")
private AuthenticationManager authenticationManager1;
@Autowired
private JwtTokenProvider1 tokenProvider1;
@PostMapping(path = "/registerNode")
public ResponseEntity<?> registerUser(@Valid @RequestBody SignUpRequest signUpRequest) {
if (user1Repository.existsByEmail(signUpRequest.getEmail())) {
return new ResponseEntity(new ApiResponse(false, "Email Address already taken"), HttpStatus.BAD_REQUEST);
}
if (user1Repository.existsByUsername(signUpRequest.getUsername())) {
return new ResponseEntity(new ApiResponse(false, "Username already taken"), HttpStatus.BAD_REQUEST);
}
// Creating User
User1 user1 = new User1(signUpRequest.getUsername(), signUpRequest.getEmail(), passwordEncoder.encode(signUpRequest.getPassword()),
signUpRequest.getFirstName(), signUpRequest.getMiddleName(), signUpRequest.getLastName());
// Role userRole = roleRepo.findByName(RoleName.ROLE_USER)
// .orElseThrow(() -> new AppException("User Role not set."));
//
// Role adminRole = roleRepo.findByName(RoleName.ROLE_ADMIN)
// .orElseThrow(() -> new AppException("User Role not set."));
//
// Set<Role> rules = new HashSet<>();
// rules.add(userRole);
// rules.add(adminRole);
// user.setRoles(rules);
User1 result = user1Repository.save(user1);
return ResponseEntity.ok(result);
}
@PostMapping("/authenticateNode")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
try {
Authentication authentication = authenticationManager1.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String accessToken = tokenProvider1.generateAccessToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(accessToken,tokenProvider1.getIssuedDateFromAccessToken(accessToken),tokenProvider1.getExpirationDateFromAccessToken(accessToken)));
} catch (BadCredentialsException exception) {
throw new BadRequestException("Wrong username or password!");
}
}
}
错误为:java.lang.RuntimeException:java.lang.IllegalArgumentException:找到2个类型为接口org.springframework.security.authentication.AuthenticationManager的bean,但未将其标记为主要类型
如果我运行一个主要代码,但对于不是主要响应的控制器,则是>
{ "timestamp": "2020-06-04T03:45:45.638+02:00", "status": 401, "error": "Unauthorized", "message": "", "path": "/api/node/auth/registerNode" }
如何进行这项工作?谢谢您的帮助
我需要具有两个不同登录/注册端点的Spring Boot应用,其中一个是api / user / auth / registerUser和api / node / auth / registerNode。我写了代码,但是现在我有两个authenticationManagerBean参见...
以下实施的类似要求对我有效:
以上是关于具有两个身份验证的Spring boot应用。 AuthenticationManager bean问题的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot:使用 Junit 模拟具有安全上下文的用户身份验证
Spring boot 如何让 Thymeleaf 网页和 REST API 具有不同的身份验证方案
具有基本身份验证和 OAuth 顺序问题的 Spring Boot 安全性