required a bean of type org.springframework.security.authentication.AuthenticationManager

huangapple go评论88阅读模式
英文:

required a bean of type org.springframework.security.authentication.AuthenticationManager

问题

以下是翻译好的代码部分:

AuthController.java

package com.cps.controllers;

// ...(省略导入语句)...

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    UserRepository userRepository;

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    PasswordEncoder encoder;

    @Autowired
    JwtUtils jwtUtils;

    @PostMapping("/signin")
    public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {

        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));

        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateJwtToken(authentication);

        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        List<String> roles = userDetails.getAuthorities().stream()
                .map(item -> item.getAuthority())
                .collect(Collectors.toList());

        return ResponseEntity.ok(new JwtResponse(jwt,
                userDetails.getId(),
                userDetails.getUsername(),
                userDetails.getEmail(),
                roles));
    }

    @PostMapping("/signup")
    public ResponseEntity<?> registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
        // ...(省略部分代码)...
    }
}

WebSecurityConfig.java

package com.cps.NormalSecurity;

// ...(省略导入语句)...

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    @Autowired
    private AuthEntryPointJwt unauthorizedHandler;

    @Bean
    public AuthTokenFilter authenticationJwtTokenFilter() {
        return new AuthTokenFilter();
    }

    @Override
    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    @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("/api/auth/**").permitAll()
                .antMatchers("/api/test/**").permitAll()
                .anyRequest().authenticated();

        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

在这段代码中,你遇到了一个错误:

Field authenticationManager in com.cps.controllers.AuthController required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.

这是因为在AuthController中,authenticationManager的注入需要一个org.springframework.security.authentication.AuthenticationManager类型的bean,但是系统没有找到这个bean。

为了解决这个问题,你可以在配置类WebSecurityConfig中定义一个AuthenticationManager的bean,让Spring能够注入到AuthController中。在已经提供的WebSecurityConfig代码中,已经包含了这部分的配置。你只需要确保代码被正确导入并配置即可。

如果你的问题解决了,请让我知道,如果还需要其他帮助,请随时提问。

英文:

This is the rest controller file..


import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cps.models.ERole;
import com.cps.models.Role;
import com.cps.models.User;
import com.cps.requests.LoginRequest;
import com.cps.requests.SignupRequest;
import com.cps.response.JwtResponse;
import com.cps.response.MessageResponse;
import com.cps.repository.RoleRepository;
import com.cps.repository.UserRepository;
import com.cps.security.jwt.JwtUtils;
import com.cps.security.services.UserDetailsImpl;
@CrossOrigin(origins = &quot;*&quot;, maxAge = 3600)
@RestController
@RequestMapping(&quot;/api/auth&quot;)
public class AuthController { 
@Autowired
AuthenticationManager authenticationManager;
@Autowired
UserRepository userRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
PasswordEncoder encoder;
@Autowired
JwtUtils jwtUtils;
@PostMapping(&quot;/signin&quot;)
public ResponseEntity&lt;?&gt; authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();		
List&lt;String&gt; roles = userDetails.getAuthorities().stream()
.map(item -&gt; item.getAuthority())
.collect(Collectors.toList());
return ResponseEntity.ok(new JwtResponse(jwt, 
userDetails.getId(), 
userDetails.getUsername(), 
userDetails.getEmail(), 
roles));
}
@PostMapping(&quot;/signup&quot;)
public ResponseEntity&lt;?&gt; registerUser(@Valid @RequestBody SignupRequest signUpRequest) {
if (userRepository.existsByUsername(signUpRequest.getUsername())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse(&quot;Error: Username is already taken!&quot;));
}
if (userRepository.existsByEmail(signUpRequest.getEmail())) {
return ResponseEntity
.badRequest()
.body(new MessageResponse(&quot;Error: Email is already in use!&quot;));
}
// Create new user&#39;s account
User user = new User(signUpRequest.getUsername(), 
signUpRequest.getEmail(),
encoder.encode(signUpRequest.getPassword()));
Set&lt;String&gt; strRoles = signUpRequest.getRole();
Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
if (strRoles == null) {
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
.orElseThrow(() -&gt; new RuntimeException(&quot;Error: Role is not found.&quot;));
roles.add(userRole);
} else {
strRoles.forEach(role -&gt; {
switch (role) {
case &quot;admin&quot;:
Role adminRole = roleRepository.findByName(ERole.ROLE_ADMIN)
.orElseThrow(() -&gt; new RuntimeException(&quot;Error: Role is not found.&quot;));
roles.add(adminRole);
break;
case &quot;mod&quot;:
Role modRole = roleRepository.findByName(ERole.ROLE_MODERATOR)
.orElseThrow(() -&gt; new RuntimeException(&quot;Error: Role is not found.&quot;));
roles.add(modRole);
break;
default:
Role userRole = roleRepository.findByName(ERole.ROLE_USER)
.orElseThrow(() -&gt; new RuntimeException(&quot;Error: Role is not found.&quot;));
roles.add(userRole);
}
});
}
user.setRoles(roles);
userRepository.save(user);
return ResponseEntity.ok(new MessageResponse(&quot;User registered successfully!&quot;));
}
}

This is the webSecurityConfig file...

package com.cps.NormalSecurity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.cps.security.jwt.AuthEntryPointJwt;
import com.cps.security.jwt.AuthTokenFilter;
import com.cps.security.services.UserDetailsServiceImpl;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,jsr250Enabled = true,prePostEnabled = true)  
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
UserDetailsServiceImpl userDetailsService;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@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(&quot;/api/auth/**&quot;).permitAll()
.antMatchers(&quot;/api/test/**&quot;).permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
}

Description:

Field authenticationManager in com.cps.controllers.AuthController required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.

The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:

Consider defining a bean of type 'org.springframework.security.authentication.AuthenticationManager' in your configuration.
Any idea???

答案1

得分: 1

这种用于初始化您的 bean 的方法:

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

默认情况下,Spring 会将 bean 的名称与 bean 初始化方法的名称相同。因此在您的项目中,Spring 会创建一个类型为 AuthenticationManager 的 bean,其名称为 authenticationManagerBean
因此,您现在有三个选项:

  • 在自动装配字段时使用 @Qualifier("authenticationManagerBean")(如 @harry 所提到的)
  • 在您的控制器类中使用 Spring 的默认 bean 名称
@Autowired
private AuthenticationManager authenticationManagerBean;
  • 将 bean 初始化方法的名称更改为 authenticationManager
英文:

This method you are using for initializing your bean:

    @Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

By default, spring creates the bean's name the same as the bean initializing method name. So in your project, spring creates a bean of type AuthenticationManager named as authenticationManagerBean.
So you now have three options:

  • use @Qualifier(&quot;authenticationManagerBean&quot;) while autowiring the field (as mentioned by @harry)
  • use the spring's default bean name in your controller class
    @Autowired
private AuthenticationManager authenticationManagerBean;
  • change the bean initializing method's name to authenticationManager

答案2

得分: 0

在控制器类(AuthController)中添加限定符,以便访问该 Bean。

@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
英文:

Add qualifier in the controller class (AuthController) in order to access the bean.

 @Autowired
@Qualifier(&quot;authenticationManagerBean&quot;)
private AuthenticationManager authenticationManager;

huangapple
  • 本文由 发表于 2020年7月25日 18:19:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63087156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定