这是我第一次尝试在JSF项目中配置Spring安全性。我使用过Spring MVC和Spring Boot项目,我没有遇到任何问题。
我使用网上看到的一些示例以及Spring Security 4.2.1.RELEASE本身的文档
我有依赖注入错误:
没有符合条件的类型' com.sgr.security.AppUserDetailService' 可用:预计至少有1个符合autowire资格的bean 候选人。依赖注释:{@ javax.inject.Inject()}
我已经报告了ComponentScan注释,但它无法正常工作
Tecnologias usadas:
Spring Security 4.2.1.RELEASE(spring-framework-bom 4.3.5.RELEASE)
Spring Data Hopper-SR6(spring-data-releasetrain)
WebSecurityConfig.class
package com.sgr.config;
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 org.springframework.security.crypto.password.PasswordEncoder;
import com.sgr.security.AppUserDetailService;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Inject
private AppUserDetailService userDetailsService;
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(encoder());
return authProvider;
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder(11);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/login.xhtml", "/javax.faces.resource/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login.xhtml");
}
}
SecurityWebApplicationInitializer.class
package com.sgr.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(WebSecurityConfig.class);
}
}
AppUserDetailService.class
package com.sgr.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.sgr.domain.Usuario;
import com.sgr.repositorio.IRepositorioUsuario;
public class AppUserDetailService implements UserDetailsService {
@Inject
private IRepositorioUsuario usuarioRepository;
@Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
Usuario usuario = usuarioRepository.findByLogin(login);
if (usuario == null) {
throw new UsernameNotFoundException("Nenhum Usuário encontrado!");
}else {
return new UsuarioSistema(usuario, getGrupos(usuario)) ;
}
}
private Collection<? extends GrantedAuthority> getGrupos(Usuario usuario) {
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
List<String> grupos = usuarioRepository.findByNameGrupoPermissao(usuario.getLogin());
grupos.forEach(s -> authorities.add(new SimpleGrantedAuthority("ROLE_"+s)));
return authorities;
}
}
IRepositorioUsuario.class
public interface IRepositorioUsuario extends CrudRepository<Usuario, Long> {
public Usuario findByLogin(String login);
@Query("SELECT grp.nome FROM Usuario usr, Permissao per, GrupoPermissao grp "
+ "WHERE usr.login = ? AND per.codigo = usr.codigo AND grp.codigo = per.codigo")
public List<String> findByNameGrupoPermissao(String Login);
}
Usuario.class
@Entity
@Table(name="TUSUARIO")
public class Usuario implements Serializable {
private static final long serialVersionUID = -5427866189669150032L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long codigo;
@NotBlank(message="Campo Nome não pode ser vazio!")
private String nome;
@NotBlank(message="Campo Login não pode ser vazio!")
private String login;
@NotBlank(message="Campo Senha não pode ser vazio!")
private String senha;
@Column(name="DATACAD")
private Date dataCadastro;
private Boolean situacao;
// get and set...
UsuarioSistema.class
public class UsuarioSistema extends User {
private static final long serialVersionUID = 1L;
private Usuario usuario;
public UsuarioSistema(Usuario usuario, Collection<? extends GrantedAuthority> authorities) {
super(usuario.getLogin(), usuario.getSenha(), authorities);
}
public Usuario getUsuario() {
return usuario;
}
}
LoginBean.class
@Named(value="loginBean")
@SessionScoped
public class LoginBean extends AbstractBean {
private static final long serialVersionUID = 1L;
@Inject
private FacesContext facesContext;
@Inject
private HttpServletRequest request;
@Inject
private HttpServletResponse response;
private String login;
public void preRender() {
if ("true".equals(request.getParameter("invalid"))) {
addError(true, "Usuário ou senha inválido!", null);
}
}
public void login() throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher("/login.xhtml");
dispatcher.forward(request, response);
facesContext.responseComplete();
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
}
的login.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
xmlns:jsf="http://xmlns.jcp.org/jsf">
<h:head>
<title>Login Restaurante Web</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<h:outputStylesheet library="bootstrap" name="css/bootstrap.min.css"/>
<h:outputStylesheet library="dist" name="css/AdminLTE.min.css"/>
</h:head>
<h:body class="hold-transition login-page">
<f:metadata>
<f:viewParam name="dummy" />
<f:event listener="#{loginBean.preRender}" type="preRenderView" />
</f:metadata>
<div class="login-box">
<div class="login-logo">
<a><b>Restaurante</b>WEB</a>
</div>
<div class="row">
<div class="col-sm-12">
<p:messages id="messages" closable="true"/>
</div>
</div>
<div class="login-box-body">
<p class="login-box-msg">Bem Vindo!</p>
<h:form id="formLogin">
<div class="form-group has-feedback">
<p:inputText pt:autocorrect="off"
pt:spellcheck="false"
pt:autocomplete="off"
pt:autocapitalize="off"
styleClass="form-control"
placeholder="Login"
id="login" value="#{loginBean.login}"/>
<span class="fa fa-user form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<p:password pt:autocorrect="off"
pt:spellcheck="false"
styleClass="form-control"
placeholder="Senha"/>
<span class="fa fa-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-4">
<button type="submit"
jsf:update="@form,messages"
jsf:process="@form"
class="btn btn-primary btn-block btn-flat"
jsf:action="#{loginBean.login()}" >
Login
</button>
</div>
</div>
<div class="row">
<div align="center" class="col-xs-12">
<i class="fa fa-hand-o-right"></i>
<span class="text-bold">
<a href="#">Esqueci minha Senha</a>
</span>
</div>
</div>
</h:form>
</div>
</div>
<h:outputScript library="plugins" name="jQuery/jQuery-2.1.4.min.js"/>
<h:outputScript library="bootstrap" name="js/bootstrap.min.js"/>
</h:body>
</html>
Log_ERRO
20:12:46,453 INFO [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor] (ServerService Thread Pool -- 76) JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
20:12:46,747 WARN [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] (ServerService Thread Pool -- 76) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
20:12:46,751 ERROR [org.springframework.web.context.ContextLoader] (ServerService Thread Pool -- 76) Context initialization failed: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:200)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:171)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:234)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 35 more
20:12:46,754 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 76) MSC000001: Failed to start service jboss.undertow.deployment.default-server.default-host./sgr: org.jboss.msc.service.StartException in service jboss.undertow.deployment.default-server.default-host./sgr: java.lang.RuntimeException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:85)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: java.lang.RuntimeException: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:236)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:100)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:82)
... 6 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:552)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:200)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:171)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:234)
... 8 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.sgr.security.AppUserDetailService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject()}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 35 more
答案 0 :(得分:0)
您应该在AppUserDetailService类中添加Component
注释。 ComponentScan意味着spring将为具有Component Annotation的类提供bean实例。