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

huangapple 未分类评论45阅读模式
英文:

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://java.coder-hub.com/63087156.html
匿名

发表评论

匿名网友

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

确定